Refactored Python client to match other clients.
This commit is contained in:
@@ -5,259 +5,301 @@ class XPlaneConnect:
|
|||||||
'''XPlaneConnect (XPC) facilitates communication to and from the XPCPlugin.'''
|
'''XPlaneConnect (XPC) facilitates communication to and from the XPCPlugin.'''
|
||||||
|
|
||||||
# Basic Functions
|
# Basic Functions
|
||||||
def __init__(self, port, xp_ip = 'localhost', xp_port = 49009):
|
def __init__(self, xpHost = 'localhost', xpPort = 49009, port = 0, timeout = 100):
|
||||||
'''Creates a new XPlaneConnect interface, and binds a UDP socket based on the specified parameters.'''
|
'''Sets up a new connection to an X-Plane Connect plugin running in X-Plane.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
xpHost: The hostname of the machine running X-Plane.
|
||||||
|
xpPort: The port on which the XPC plugin is listening. Usually 49007.
|
||||||
|
port: The port which will be used to send and receive data.
|
||||||
|
timeout: The period (in milliseconds) after which read attempts will fail.
|
||||||
|
'''
|
||||||
|
|
||||||
# Setup server port
|
# Validate parameters
|
||||||
self.server = ("0.0.0.0", port)
|
xpIP = None
|
||||||
|
try:
|
||||||
|
xpIP = socket.gethostbyname(xpHost)
|
||||||
|
except:
|
||||||
|
raise ValueError("Unable to resolve xpHost.")
|
||||||
|
|
||||||
|
if xpPort < 0 or xpPort > 65535:
|
||||||
|
raise ValueError("The specified X-Plane port is not a valid port number.")
|
||||||
|
if port < 0 or port > 65535:
|
||||||
|
raise ValueError("The specified port is not a valid port number.")
|
||||||
|
if timeout < 0:
|
||||||
|
raise ValueError("timeout must be non-negative.")
|
||||||
|
|
||||||
# Setup XPlane IP and port
|
# Setup XPlane IP and port
|
||||||
if xp_ip == 'localhost' or xp_ip is None:
|
self.xpDst = (socket.inet_pton(socket.AF_INET, xpIP), xpPort)
|
||||||
self.xp_ip = '127.0.0.1'
|
|
||||||
else:
|
|
||||||
self.xp_ip = xp_ip
|
|
||||||
|
|
||||||
self.xp_port = xp_port
|
# Create and bind socket
|
||||||
|
clientAddr = (socket.INADDR_ANY, port)
|
||||||
# Create and bind socket
|
|
||||||
# TODO: Raise a friendly error if socket creation/binding fails
|
|
||||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
|
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
|
||||||
self.socket.bind(self.server)
|
self.socket.bind(clientAddr)
|
||||||
|
self.socket.settimeout(timeout / 1000)
|
||||||
# Set timeout
|
|
||||||
timeout_us = 500
|
|
||||||
self.socket.settimeout(timeout_us / 1000000)
|
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
'''Closes the underlying UDP socket'''
|
'''Closes the specified connection and releases resources associated with it.'''
|
||||||
if self.socket is not None:
|
if self.socket is not None:
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
self.socket = None
|
self.socket = None
|
||||||
|
|
||||||
def send_udp(self, msg):
|
def sendUDP(self, buffer):
|
||||||
'''Sends a message over the underlying UDP socket.'''
|
'''Sends a message over the underlying UDP socket.'''
|
||||||
msg_len = len(msg)
|
|
||||||
msg = list(msg)
|
|
||||||
msg[4] = chr(msg_len)
|
|
||||||
msg = "".join(msg)
|
|
||||||
|
|
||||||
# Preconditions
|
# Preconditions
|
||||||
if(msg_len <= 0): # Require message length greater than 0.
|
if(len(buffer) == 0):
|
||||||
raise RuntimeError("send_udp: message length must be psoitive >0")
|
raise ValueError("sendUDP: buffer is empty.")
|
||||||
|
|
||||||
on = 1
|
self.socket.sendto(buffer, 0, self.xpDst)
|
||||||
# Code
|
|
||||||
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, on)
|
|
||||||
|
|
||||||
self.socket.sendto(msg, 0, (self.xp_ip, self.xp_port))
|
def readUDP(self):
|
||||||
|
'''Reads a message from the underlying UDP socket.'''
|
||||||
def read_udp(self, recv_addr = None):
|
return self.socket.recv(16384)
|
||||||
if recv_addr is None:
|
|
||||||
recv_addr = (self.xp_ip, self.xp_port)
|
|
||||||
|
|
||||||
return self.socket.recv(5000) # TODO: Validate that this matches the behavior of the C version
|
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
def set_conn(self, rec_port):
|
def setCONN(self, port):
|
||||||
msg = struct.pack("!4sH", ("CONN", rec_port))
|
'''Sets the port on which the client sends and receives data.
|
||||||
self.send_udp(msg)
|
|
||||||
|
Args:
|
||||||
|
port: The new port to use.
|
||||||
|
'''
|
||||||
|
#Validate parameters
|
||||||
|
if port < 0 or port > 65535:
|
||||||
|
raise ValueError("The specified port is not a valid port number.")
|
||||||
|
|
||||||
def pause_sim(self, pause):
|
buffer = struct.pack("<4sxH", ("CONN", port))
|
||||||
'''Pauses or unpauses the X-Plane simulation'''
|
self.sendUDP(buffer)
|
||||||
|
|
||||||
|
def pauseSim(self, pause):
|
||||||
|
'''Pauses or un-pauses the physics simulation engine in X-Plane.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
pause: True to pause the simulation; False to resume.
|
||||||
|
'''
|
||||||
pause_val = 0
|
pause_val = 0
|
||||||
if pause:
|
if pause:
|
||||||
pause_val = 1
|
pause_val = 1
|
||||||
|
|
||||||
msg = struct.pack("4sBB", ("SIMU", pause_val, 0))
|
buffer = struct.pack("<4sxB", ("SIMU", pause_val))
|
||||||
self.send_udp(msg)
|
self.sendUDP(buffer)
|
||||||
|
|
||||||
# UDP Data
|
# X-Plane UDP Data
|
||||||
def parse_data(self, msg):
|
def readDATA(self):
|
||||||
total_cols = ((len(data) - 5) / 36)
|
'''Reads X-Plane data.
|
||||||
data = []
|
|
||||||
|
|
||||||
# Input Validation
|
|
||||||
for i in range(total_cols):
|
|
||||||
data.append([])
|
|
||||||
data[i].append(struct.unpack_from("f", msg, 5 + 36*i))
|
|
||||||
for j in range(1, 9):
|
|
||||||
data[i].append(struct.unpack_from("f", msg, 5 + 4*j + 36*i))
|
|
||||||
|
|
||||||
return data
|
Returns: A 2 dimensional array containing 0 or more rows of data. Each array
|
||||||
|
in the result will have 9 elements, the first of which is the row number which
|
||||||
def read_data(self):
|
that array represents data for, and the rest of which are the data elements in
|
||||||
buf = self.read_udp()
|
that row.
|
||||||
if buf[0] != 0:
|
'''
|
||||||
return self.parse_data(buf)
|
buffer = self.readUDP();
|
||||||
else:
|
if len(buffer) < 6:
|
||||||
return None
|
return None
|
||||||
|
rows = (len(buffer) - 5) / 36
|
||||||
|
data = []
|
||||||
|
for i in range(rows):
|
||||||
|
data.append(struct.unpack_from("9f", buffer, 5 + 36*i))
|
||||||
|
return data
|
||||||
|
|
||||||
def send_data(self, dataRef):
|
def sendDATA(self, data):
|
||||||
'''Sends X-Plane data over the underlying UDP socket.'''
|
'''Sends X-Plane data over the underlying UDP socket.
|
||||||
msg = struct.pack("4s", "DATA")
|
|
||||||
for row in dataRef:
|
Args:
|
||||||
struct.pack_into("!I", msg, len(msg), row[0])
|
data: An array of values representing data rows to be set. Each array in `data`
|
||||||
for i in range(8):
|
should have 9 elements, the first of which is a row number in the range (0-134),
|
||||||
struct.pack_into("!f", msg, len(msg), row[1][i])
|
and the rest of which are the values to set for that data row.
|
||||||
self.send_udp(msg)
|
'''
|
||||||
|
if len(data) > 134:
|
||||||
|
raise ValueError("Too many rows in data.")
|
||||||
|
|
||||||
|
buffer = struct.pack("4sx", "DATA")
|
||||||
|
for row in data:
|
||||||
|
if len(row) != 9:
|
||||||
|
raise ValueError("Row does not contain exactly 9 values. <" + str(row) + ">")
|
||||||
|
struct.pack_into("<I8f", buffer, len(buffer), row)
|
||||||
|
self.sendUDP(buffer)
|
||||||
|
|
||||||
# Position
|
# Position
|
||||||
def parse_pos(self, msg, array_size):
|
def sendPOSI(self, values, ac = 0):
|
||||||
if array_size < 1:
|
'''Sets position information on the specified aircraft.
|
||||||
return None
|
|
||||||
|
|
||||||
gear = struct.unpack_from("f", msg, 30)
|
Args:
|
||||||
result = []
|
values: The position values to set. `values` is a array containing up to
|
||||||
for i in range(min(array_size, 6)):
|
7 elements. If less than 7 elements are specified or any elment is set to `-998`,
|
||||||
result.append(struct.unpack_from("f", msg, i*4 + 6))
|
those values will not be changed. The elements in `values` corespond to the
|
||||||
|
following:
|
||||||
return result, gear
|
* Latitude (deg)
|
||||||
|
* Longitude (deg)
|
||||||
def read_pos(self, resultArray, gear):
|
* Altitude (m above MSL)
|
||||||
buf = self.read_udp()
|
* Roll (deg)
|
||||||
if buf[0] != 0:
|
* Pitch (deg)
|
||||||
return self.parse_pos(buf)
|
* True Heading (deg)
|
||||||
else:
|
* Gear (0=up, 1=down)
|
||||||
return None
|
ac: The aircraft to set the control surfaces of. 0 is the main/player aircraft.
|
||||||
|
'''
|
||||||
def send_pos(self, ac_num, values):
|
|
||||||
# Preconditions
|
# Preconditions
|
||||||
if len(values) < 1:
|
if len(values) < 1 or len(values) > 7:
|
||||||
raise RuntimeError("send_pos: Must have at least one argument")
|
raise ValueError("Must have between 0 and 7 items in values.")
|
||||||
|
if ac < 0 or ac > 20:
|
||||||
|
raise ValueError("Aircraft number must be between 0 and 20.")
|
||||||
|
|
||||||
# Header and Aircraft num
|
# Pack message
|
||||||
msg = struct.pack("!4sB", ("POSI", ac_num))
|
buffer = struct.pack("<4sxB", ("POSI", ac))
|
||||||
# States
|
|
||||||
for i in range(7):
|
for i in range(7):
|
||||||
val = -998.5 # TODO: Why?
|
val = -998
|
||||||
if i < len(values):
|
if i < len(values):
|
||||||
val = values[i]
|
val = values[i]
|
||||||
struct.pack_into("!f", msg, len(msg), val)
|
struct.pack_into("<f", buffer, len(buffer), val)
|
||||||
|
|
||||||
# Send
|
# Send
|
||||||
self.send_udp(msg)
|
self.sendUDP(buffer)
|
||||||
|
|
||||||
# Controls
|
# Controls
|
||||||
def parse_ctrl(self, msg):
|
def sendCTRL(self, values, ac = 0):
|
||||||
result = []
|
'''Sets control surface information on the specified aircraft.
|
||||||
for i in range(4):
|
|
||||||
result.append(struct.unpack_from("f", msg, i*4 + i))
|
|
||||||
gear = struct.unpack_from("B", msg, 21)
|
|
||||||
flaps = struct.unpack_from("f", msg, 22)
|
|
||||||
return flaps, gear, result
|
|
||||||
|
|
||||||
def read_ctrol(self, resultArray, gear):
|
Args:
|
||||||
buf = self.read_udp()
|
values: The control surface values to set. `values` is a array containing up to
|
||||||
if buf[0] != 0:
|
6 elements. If less than 6 elements are specified or any elment is set to `-998`,
|
||||||
return self.parse_ctrl(buf)
|
those values will not be changed. The elements in `values` corespond to the
|
||||||
else:
|
following:
|
||||||
return float("NaN")
|
* Latitudinal Stick [-1,1]
|
||||||
|
* Longitudinal Stick [-1,1]
|
||||||
def send_ctrol(self, values):
|
* Rudder Pedals [-1, 1]
|
||||||
|
* Throttle [-1, 1]
|
||||||
|
* Gear (0=up, 1=down)
|
||||||
|
* Flaps [0, 1]
|
||||||
|
ac: The aircraft to set the control surfaces of. 0 is the main/player aircraft.
|
||||||
|
'''
|
||||||
# Preconditions
|
# Preconditions
|
||||||
if len(values) < 1:
|
if len(values) < 1 or len(values) > 6:
|
||||||
raise RuntimeError("send_ctrl: Must have at least one argument")
|
raise ValueError("Must have between 0 and 6 items in values.")
|
||||||
|
if ac < 0 or ac > 20:
|
||||||
|
raise ValueError("Aircraft number must be between 0 and 20.")
|
||||||
|
|
||||||
# Header
|
# Pack message
|
||||||
msg = struct.pack("!4s", "CTRL")
|
buffer = struct.pack("<4sx", "CTRL")
|
||||||
|
|
||||||
# States
|
|
||||||
for i in range(6):
|
for i in range(6):
|
||||||
val = -998.5 # TODO: Why?
|
val = -998
|
||||||
if i < len(values):
|
if i < len(values):
|
||||||
val = values[i]
|
val = values[i]
|
||||||
struct.pack_into("!f", msg, len(msg), val)
|
struct.pack_into("<f", buffer, len(buffer), val)
|
||||||
|
struct.pack_into("B", buffer, len(buffer), ac)
|
||||||
|
|
||||||
# Send
|
# Send
|
||||||
self.send_udp(msg)
|
self.sendUDP(buffer)
|
||||||
|
|
||||||
# DREF Manipulation
|
# DREF Manipulation
|
||||||
def read_dref(self):
|
def sendDREF(self, dref, values):
|
||||||
buf = self.read_udp()
|
'''Sets the specified dataref to the specified value.
|
||||||
if buf[0] != 0:
|
|
||||||
return self.parse_dref(buf)
|
Args:
|
||||||
|
dref: The name of the dataref to set.
|
||||||
|
values: Either a scalar value or a sequence of values.
|
||||||
|
'''
|
||||||
|
# Preconditions
|
||||||
|
if len(dref) == 0 or len(dref) > 255:
|
||||||
|
raise ValueError("dref must be a non-empty string less than 256 characters.")
|
||||||
|
if values == None:
|
||||||
|
raise ValueError("values must be a scalar or sequence of floats.")
|
||||||
|
|
||||||
|
# Pack message
|
||||||
|
fmt = ""
|
||||||
|
buffer = None
|
||||||
|
if hasattr(values, "__len__"):
|
||||||
|
if len(values) > 255:
|
||||||
|
raise ValueError("values must have less than 256 items.")
|
||||||
|
fmt = "<4sxB" + len(dref) + "sB" + len(values) + "f"
|
||||||
|
buffer = struct.pack(fmt, ("DREF", len(dref), dref, len(values), values))
|
||||||
else:
|
else:
|
||||||
return None
|
fmt = "<4sxB" + len(dref) + "sBf"
|
||||||
|
buffer = struct.pack(fmt, ("DREF", len(dref), dref, 1, values))
|
||||||
|
|
||||||
def parse_dref(self, msg):
|
# Send
|
||||||
len_dref = struct.unpack_from("B", msg, 5)
|
self.sendUDP(buffer)
|
||||||
dref = struct.unpack_from(str(len_dref) + "B", msg, 6)
|
|
||||||
len_val = struct.unpack_from("B", msg, 6 + len_dref)
|
|
||||||
values = struct.unpack_from(str(len_val) + "f", msg, 7 + len_dref)
|
|
||||||
return dref, values
|
|
||||||
|
|
||||||
def send_dref(self, data_ref, values):
|
def getDREF(self, dref):
|
||||||
'''Sends X-Plane dref over the underlying UDP socket.'''
|
'''Gets the value of an X-Plane dataref.
|
||||||
msg_len = 7 + len(data_ref) + len(values) * 4
|
|
||||||
|
Args:
|
||||||
# Header
|
dref: The name of the dataref to get.
|
||||||
msg = struct.pack("4s", "DREF")
|
|
||||||
|
|
||||||
# DRef
|
Returns: A sequence of data representing the values of the requested dataref.
|
||||||
struct.pack_into("B", msg, len(msg), len(data_ref))
|
'''
|
||||||
struct.pack_into(str(len(data_ref)) + "B", msg, len(msg), data_ref) # TODO: Verify byte order (should be network order?)
|
return getDREFS([dref])[0]
|
||||||
|
|
||||||
# Values
|
def getDREFs(self, drefs):
|
||||||
struct.pack_into("B", msg, len(msg), len(values))
|
'''Gets the value of one or more X-Plane datarefs.
|
||||||
struct.pack_into(str(len(values)) + "f", msg, len(msg), values) # TODO: Verify byte order (should be network order?)
|
|
||||||
|
|
||||||
self.send_udp(msg)
|
Args:
|
||||||
|
drefs: The names of the datarefs to get.
|
||||||
|
|
||||||
def request_dref(self, dref_array):
|
Returns: A multidimensional sequence of data representing the values of the requested
|
||||||
'''Requests drefs and reads the response.'''
|
datarefs.
|
||||||
self.send_request(dref_array)
|
'''
|
||||||
for i in range(80):
|
# Send request
|
||||||
result = self.read_dref()
|
buffer = struct.pack("<4sxB" ("GETD", len(drefs)))
|
||||||
if siresultze is not None:
|
for dref in drefs:
|
||||||
return result
|
struct.pack_into("<B" + len(dref) + "s", buffer, len(buffer), dref)
|
||||||
|
self.sendUDP(buffer)
|
||||||
|
|
||||||
return None
|
# Read and parse response
|
||||||
|
buffer = self.readUDP()
|
||||||
def parse_getd(self, msg, dref_array, dref_sizes):
|
resultCount = struct.unpack_from("B", buffer, 5)
|
||||||
len_list = struct.unpack_from("B", msg, 5)
|
offset = 6
|
||||||
counter = 6
|
|
||||||
drefs = []
|
|
||||||
|
|
||||||
for i in range(len_list):
|
|
||||||
dref_size = struct.unpack_from("B", msg, counter)
|
|
||||||
drefs.append(struct.unpack_from(str(dref_size) + "B", msg, counter + 1))
|
|
||||||
counter += dref_size + 1
|
|
||||||
|
|
||||||
return drefs
|
|
||||||
|
|
||||||
def send_request(self, dref_array):
|
|
||||||
'''Sends a request over the underlying UDP socket.'''
|
|
||||||
# Header
|
|
||||||
msg = struct.pack("4s", "GETD");
|
|
||||||
|
|
||||||
# Number of values;
|
|
||||||
struct.pack_into("B", msg, len(msg), len(dref_array))
|
|
||||||
|
|
||||||
# The Rest
|
|
||||||
for dref in dref_array:
|
|
||||||
struct.pack_into("B", msg, len(msg), len(dref_array))
|
|
||||||
struct.pack_into("100B", msg, len(msg), dref_array)
|
|
||||||
|
|
||||||
self.send_udp(msg)
|
|
||||||
|
|
||||||
def parse_request(self, msg):
|
|
||||||
count = msg[5]
|
|
||||||
cursor = 6
|
|
||||||
result = []
|
result = []
|
||||||
for i in range(count):
|
for i in range(resultCount):
|
||||||
arr_size = msg[cursor]
|
rowLen = struct.unpack_from("B", buffer, offset)
|
||||||
data = struct.unpack_from(str(arr_size) + "f", msg, cursor)
|
offset += 1
|
||||||
result.append(data)
|
row = struct.unpack_from("<" + rowLen + "f", buffer, offset)
|
||||||
cursor += arr_size
|
result.append(row)
|
||||||
|
offset += rowLen * 4
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def read_request(self, recv_addr):
|
# Drawing
|
||||||
buf = self.read_udp()
|
def sendTEXT(self, msg, x = -1, y = -1):
|
||||||
if buf[0] != 0:
|
'''Sets a message that X-Plane will display on the screen.
|
||||||
return self.parse_request(buf)
|
|
||||||
else:
|
Args:
|
||||||
return None
|
msg: The string to display on the screen
|
||||||
|
x: The distance in pixels from the left edge of the screen to display the
|
||||||
|
message. A value of -1 indicates that the default horizontal position should
|
||||||
|
be used.
|
||||||
|
y: The distance in pixels from the bottom edge of the screen to display the
|
||||||
|
message. A value of -1 indicates that the default vertical position should be
|
||||||
|
used.
|
||||||
|
'''
|
||||||
|
if y < -1:
|
||||||
|
raise ValueError("y must be greater than or equal to -1.")
|
||||||
|
|
||||||
|
if msg == None:
|
||||||
|
msg = ""
|
||||||
|
|
||||||
|
msgLen = len(msg)
|
||||||
|
buffer = struct.pack("<4sxiiB" + msgLen + "s", ("TEXT", x, y, msgLen, msg))
|
||||||
|
self.sendUDP(buffer)
|
||||||
|
|
||||||
|
def sendWYPT(self, op, points):
|
||||||
|
'''Adds, removes, or clears waypoints. Waypoints are three dimensional points on or
|
||||||
|
above the Earth's surface that are represented visually in the simulator. Each
|
||||||
|
point consists of a latitude and longitude expressed in fractional degrees and
|
||||||
|
an altitude expressed as meters above sea level.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
op: The operation to perform. Pass `1` to add waypoints,
|
||||||
|
`2` to remove waypoints, and `3` to clear all waypoints.
|
||||||
|
points: A sequence of floating point values representing latitude, longitude, and
|
||||||
|
altitude triples. The length of this array should always be divisible by 3.
|
||||||
|
'''
|
||||||
|
if op < 1 or op > 3:
|
||||||
|
raise ValueError("Invalid operation specified.")
|
||||||
|
if len(points) % 3 != 0:
|
||||||
|
raise ValueError("Invalid points. Points should be divisible by 3.")
|
||||||
|
if len(points) / 3 > 255:
|
||||||
|
raise ValueError("Too many points. You can only send 255 points at a time.")
|
||||||
|
|
||||||
|
buffer = struct.pack("<4sxBB" + len(points) + "f", ("WYPT", op, len(points), points))
|
||||||
|
self.sendUDP(buffer)
|
||||||
|
|||||||
@@ -5,13 +5,13 @@
|
|||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
<ProjectGuid>3c7a940d-17c8-4e91-882f-9bc8b1d2f54b</ProjectGuid>
|
<ProjectGuid>3c7a940d-17c8-4e91-882f-9bc8b1d2f54b</ProjectGuid>
|
||||||
<ProjectHome>.</ProjectHome>
|
<ProjectHome>.</ProjectHome>
|
||||||
<StartupFile>src/xplaneConnect.py</StartupFile>
|
<StartupFile>src/XPlaneConnect.py</StartupFile>
|
||||||
<SearchPath>
|
<SearchPath>
|
||||||
</SearchPath>
|
</SearchPath>
|
||||||
<WorkingDirectory>.</WorkingDirectory>
|
<WorkingDirectory>.</WorkingDirectory>
|
||||||
<OutputPath>.</OutputPath>
|
<OutputPath>.</OutputPath>
|
||||||
<Name>xplaneConnect</Name>
|
<Name>XPlaneConnect</Name>
|
||||||
<RootNamespace>xplaneConnect</RootNamespace>
|
<RootNamespace>XPlaneConnect</RootNamespace>
|
||||||
<InterpreterId>{2af0f10d-7135-4994-9156-5d01c9c11b7e}</InterpreterId>
|
<InterpreterId>{2af0f10d-7135-4994-9156-5d01c9c11b7e}</InterpreterId>
|
||||||
<InterpreterVersion>2.7</InterpreterVersion>
|
<InterpreterVersion>2.7</InterpreterVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="src/xplaneConnect.py" />
|
<Compile Include="src/XPlaneConnect.py" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="src\" />
|
<Folder Include="src\" />
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio 2013
|
# Visual Studio 2013
|
||||||
VisualStudioVersion = 12.0.31101.0
|
VisualStudioVersion = 12.0.31101.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "xplaneConnect", "xplaneConnect.pyproj", "{3C7A940D-17C8-4E91-882F-9BC8B1D2F54B}"
|
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "XPlaneConnect", "XPlaneConnect.pyproj", "{3C7A940D-17C8-4E91-882F-9BC8B1D2F54B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "Tests", "..\TestScripts\Python Tests\Tests.pyproj", "{6931EBB2-4E01-4C5A-86B6-668C0E75051B}"
|
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "Tests", "..\TestScripts\Python Tests\Tests.pyproj", "{6931EBB2-4E01-4C5A-86B6-668C0E75051B}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|||||||
Reference in New Issue
Block a user