Module pyinsim
[hide private]
[frames] | no frames]

Source Code for Module pyinsim

   1  #!/usr/bin/env python 
   2  # 
   3  # Copyright Alex McBride 2009. 
   4  # 
   5  # This file is part of pyinsim. 
   6  # 
   7  # pyinsim is free software: you can redistribute it and/or modify 
   8  # it under the terms of the GNU Lesser General Public License as published by 
   9  # the Free Software Foundation, either version 3 of the License, or 
  10  # (at your option) any later version. 
  11  # 
  12  # pyinsim is distributed in the hope that it will be useful, 
  13  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15  # GNU Lesser General Public License for more details. 
  16  # 
  17  # You should have received a copy of the GNU Lesser General Public License 
  18  # along with pyinsim. If not, see <http://www.gnu.org/licenses/>. 
  19  # 
  20   
  21  """An InSim module for the Python programming language. 
  22   
  23  """ 
  24   
  25  # Dependencies. 
  26  import socket 
  27  import threading 
  28  import struct 
  29  import math 
  30  import re 
  31   
  32  # This is going to be a big list when I finally write it. 
  33  #__all__ = [''] 
  34   
  35  # Constants. 
  36  _INSIM_BUFFER_SIZE = 1024 
  37  INSIM_TCP = socket.SOCK_STREAM 
  38  INSIM_UDP = socket.SOCK_DGRAM 
  39   
  40  PYINSIM_VERSION = '1.5.5' 
  41   
  42  _IP_PATTERN = r'\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2\ 
  43  [0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25\ 
  44  [0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b' 
  45   
  46  _ENCODING_MAP = {'L': 'cp1252', 
  47                   'G': 'iso8859_7', 
  48                   'C': 'cp1251', 
  49                   'J': 'Shift-JIS', 
  50                   'E': 'iso8859_2', 
  51                   'T': 'iso8859_9', 
  52                   'B': 'iso8859_13', 
  53                   'H': 'cp950', 
  54                   'S': 'cp936', 
  55                   'K': 'cp949'} 
  56   
  57  _ESCAPE_MAP = {'v': '|', 
  58                 'a': '*', 
  59                 'c': ':', 
  60                 'd': '\\', 
  61                 's': '/', 
  62                 'q': '?', 
  63                 't': '"', 
  64                 'l': '<', 
  65                 'r': '>', 
  66                 '^': '^'} 
  67   
  68  MAX_PORT = 65535 
  69  MIN_PORT = 1 
  70  ADMIN_LEN = 16 
  71   
  72  # Enum for close reason. 
  73  CLOSE_REQUEST = 0 
  74  CLOSE_LFS = 1 
  75   
  76  # Enum for pyinsim events 
  77  EVT_CLOSE = 253 
  78  EVT_ERROR = 254 
  79  EVT_TIMEOUT = 255 
  80   
  81  # Enum for OutReceiver mode. 
  82  OUT_INSIM = 0 
  83  OUT_OUTSIM = 1 
  84  OUT_OUTGAUGE = 2   
  85          
  86  # Enum for packet-types 
  87  ISP_NONE = 0 
  88  ISP_ISI = 1 
  89  ISP_VER = 2 
  90  ISP_TINY = 3 
  91  ISP_SMALL = 4 
  92  ISP_STA = 5 
  93  ISP_SCH = 6 
  94  ISP_SFP = 7 
  95  ISP_SCC = 8 
  96  ISP_CPP = 9 
  97  ISP_ISM = 10 
  98  ISP_MSO = 11 
  99  ISP_III = 12 
 100  ISP_MST = 13 
 101  ISP_MTC = 14 
 102  ISP_MOD = 15 
 103  ISP_VTN = 16 
 104  ISP_RST = 17 
 105  ISP_NCN = 18 
 106  ISP_CNL = 19 
 107  ISP_CPR = 20 
 108  ISP_NPL = 21 
 109  ISP_PLP = 22 
 110  ISP_PLL = 23 
 111  ISP_LAP = 24 
 112  ISP_SPX = 25 
 113  ISP_PIT = 26 
 114  ISP_PSF = 27 
 115  ISP_PLA = 28 
 116  ISP_CCH = 29 
 117  ISP_PEN = 30 
 118  ISP_TOC = 31 
 119  ISP_FLG = 32 
 120  ISP_PFL = 33 
 121  ISP_FIN = 34 
 122  ISP_RES = 35 
 123  ISP_REO = 36 
 124  ISP_NLP = 37 
 125  ISP_MCI = 38 
 126  ISP_MSX = 39 
 127  ISP_MSL = 40 
 128  ISP_CRS = 41 
 129  ISP_BFN = 42 
 130  ISP_AXI = 43 
 131  ISP_AXO = 44 
 132  ISP_BTN = 45 
 133  ISP_BTC = 46 
 134  ISP_BTT = 47 
 135  ISP_RIP = 48 
 136  ISP_SSH = 49 
 137  ISP_OUTGAUGE = 50 
 138  ISP_OUTSIM = 51 
 139   
 140  # Enum for IS_TINY sub-type 
 141  TINY_NONE = 0 
 142  TINY_VER = 1 
 143  TINY_CLOSE = 2 
 144  TINY_PING = 3 
 145  TINY_REPLY = 4 
 146  TINY_VTC = 5 
 147  TINY_SCP = 6 
 148  TINY_SST = 7 
 149  TINY_GTH = 8 
 150  TINY_MPE = 9 
 151  TINY_ISM = 10 
 152  TINY_REN = 11 
 153  TINY_CLR = 12 
 154  TINY_NCN = 13 
 155  TINY_NPL = 14 
 156  TINY_RES = 15 
 157  TINY_NLP = 16 
 158  TINY_MCI = 17 
 159  TINY_REO = 18 
 160  TINY_RST = 19 
 161  TINY_AXI = 20 
 162  TINY_AXC = 21 
 163  TINY_RIP = 22 
 164   
 165  # Enum for IS_SMALL sub-type 
 166  SMALL_NONE = 0 
 167  SMALL_SSP = 1 
 168  SMALL_SSG = 2 
 169  SMALL_VTA = 3 
 170  SMALL_TMS = 4 
 171  SMALL_STP = 5 
 172  SMALL_RTP = 6 
 173  SMALL_NLI = 7 
 174   
 175  # Bit flags for ISI Flags 
 176  ISF_RES_0 = 1 
 177  ISF_RES_1 = 2 
 178  ISF_LOCAL = 4 
 179  ISF_MSO_COLS = 8 
 180  ISF_NLP = 16 
 181  ISF_MCI = 32 
 182   
 183  # Enum for IS_MSO UserType. 
 184  MSO_SYSTEM = 0 
 185  MSO_USER = 1 
 186  MSO_PREFIX = 2 
 187  MSO_O = 3 
 188   
 189  # Enum for IS_MSL Sound. 
 190  SND_SILENT = 0 
 191  SND_MESSAGE = 1 
 192  SND_SYSMESSAGE = 2 
 193  SND_INVALIDKEY = 3 
 194  SND_ERROR = 4 
 195   
 196  # Enum for IS_VTN Action. 
 197  VOTE_NONE = 0 
 198  VOTE_END = 1 
 199  VOTE_RESTART = 2 
 200  VOTE_QUALIFY = 3 
 201   
 202  # Enum for IS_PLA Fact. 
 203  PITLANE_EXIT = 0 
 204  PITLANE_ENTER = 1 
 205  PITLANE_NO_PURPOSE = 2 
 206  PITLANE_DT = 3 
 207  PITLANE_SG = 4 
 208   
 209  # Enum for IS_STA InGameCam. 
 210  VIEW_FOLLOW = 0 
 211  VIEW_HELI = 1 
 212  VIEW_CAM = 2 
 213  VIEW_DRIVER = 3 
 214  VIEW_CUSTOM = 4 
 215  VIEW_ANOTHER = 255 
 216   
 217  # Enum for IS_CNL Reason. 
 218  LEAVR_DISCO = 0 
 219  LEAVR_TIMEOUT = 1 
 220  LEAVR_LOSTCONN = 2 
 221  LEAVR_KICKED = 3 
 222  LEAVR_BANNED = 4 
 223  LEAVR_SECURITY = 5 
 224   
 225  # Enum for IS_PEN Penalty. 
 226  PENALTY_NONE = 0 
 227  PENALTY_DT = 1 
 228  PENALTY_DT_VALID = 2 
 229  PENALTY_SG = 3 
 230  PENALTY_SG_VALID = 4 
 231  PENALTY_30 = 5 
 232  PENALTY_45 = 6 
 233   
 234  # Enum for IS_PEN Reason. 
 235  PENR_UNKNOWN = 1 
 236  PENR_ADMIN = 2 
 237  PENR_WRONG_WAY = 3 
 238  PENR_FALSE_START = 4 
 239  PENR_SPEEDING = 5 
 240  PENR_STOP_SHORT = 6 
 241  PENR_STOP_LATE = 7 
 242   
 243  # Enum for IS_PIT Tyres. 
 244  TYRE_R1 = 0 
 245  TYRE_R2 = 1 
 246  TYRE_R3 = 2 
 247  TYRE_R4 = 3 
 248  TYRE_ROAD_SUPER = 4 
 249  TYRE_ROAD_NORMAL = 5 
 250  TYRE_HYBRID = 6 
 251  TYRE_KNOBBLY = 7 
 252  TYRE_NOT_CHANGED = 255 
 253   
 254  # Bit flags for IS_STA Flags. 
 255  ISS_GAME = 1 
 256  ISS_REPLAY = 2 
 257  ISS_PAUSED = 4 
 258  ISS_SHIFTU = 8 
 259  ISS_SHIFTU_HIGH    = 16 
 260  ISS_SHIFTU_FOLLOW = 32 
 261  ISS_SHIFTU_NO_OPT = 64 
 262  ISS_SHOW_2D = 128 
 263  ISS_FRONT_END = 256 
 264  ISS_MULTI = 512 
 265  ISS_MPSPEEDUP =    1024 
 266  ISS_WINDOWED = 2048 
 267  ISS_SOUND_MUTE = 4096 
 268  ISS_VIEW_OVERRIDE = 8192 
 269  ISS_VISIBLE = 16384 
 270   
 271  # Bit flags for IS_PIT Work. 
 272  PSE_NOTHING = 1 
 273  PSE_STOP = 2 
 274  PSE_FR_DAM = 4 
 275  PSE_FR_WHL = 8 
 276  PSE_LE_FR_DAM = 16 
 277  PSE_LE_FR_WHL = 32 
 278  PSE_RI_FR_DAM = 64 
 279  PSE_RI_FR_WHL = 128 
 280  PSE_RE_DAM = 256 
 281  PSE_RE_WHL = 512 
 282  PSE_LE_RE_DAM = 1024 
 283  PSE_LE_RE_WHL = 2048 
 284  PSE_RI_RE_DAM = 4096 
 285  PSE_RI_RE_WHL = 8192 
 286  PSE_BODY_MINOR = 16384 
 287  PSE_BODY_MAJOR = 32768 
 288  PSE_SETUP = 65536 
 289  PSE_REFUEL = 131072 
 290  PSE_NUM = 262144 
 291   
 292  # Bit flags for IS_NPL Flags. 
 293  PIF_SWAPSIDE = 1 
 294  PIF_RESERVED_2 = 2 
 295  PIF_RESERVED_4 = 4 
 296  PIF_AUTOGEARS = 8 
 297  PIF_SHIFTER = 16 
 298  PIF_RESERVED_32 = 32 
 299  PIF_HELP_B = 64 
 300  PIF_AXIS_CLUTCH = 128 
 301  PIF_INPITS = 256 
 302  PIF_AUTOCLUTCH = 512 
 303  PIF_MOUSE = 1024 
 304  PIF_KB_NO_HELP = 2048 
 305  PIF_KB_STABILISED = 4096 
 306  PIF_CUSTOM_VIEW = 8192 
 307   
 308  # Bit flags for IS_RES Confirm. 
 309  CONF_MENTIONED = 1 
 310  CONF_CONFIRMED = 2 
 311  CONF_PENALTY_DT = 4 
 312  CONF_PENALTY_SG = 8 
 313  CONF_PENALTY_30 = 16 
 314  CONF_PENALTY_45 = 32 
 315  CONF_DID_NOT_PIT = 64 
 316  CONF_DISQ = (CONF_PENALTY_DT | CONF_PENALTY_SG | CONF_DID_NOT_PIT) 
 317  CONF_TIME = (CONF_PENALTY_30 | CONF_PENALTY_45) 
 318   
 319  # Bit flags for IS_RST Flags. 
 320  HOSTF_CAN_VOTE = 1 
 321  HOSTF_CAN_SELECT = 2 
 322  HOSTF_MID_RACE = 32 
 323  HOSTF_MUST_PIT = 64 
 324  HOSTF_CAN_RESET = 128 
 325  HOSTF_FCV = 256 
 326  HOSTF_CRUISE = 512 
 327   
 328  # Bit flags for CompCar Info. 
 329  CCI_BLUE = 1 
 330  CCI_YELLOW = 2 
 331  CCI_LAG    = 32 
 332  CCI_FIRST = 64 
 333  CCI_LAST = 128 
 334   
 335  # Recomended area for IS_BTN T, L, W, H 
 336  IS_X_MIN = 0 
 337  IS_X_MAX = 110 
 338  IS_Y_MIN = 30 
 339  IS_Y_MAX = 170 
 340   
 341  # Enum for IS_BFN SubT 
 342  BFN_DEL_BTN = 0 
 343  BFN_CLEAR = 1 
 344  BFN_USER_CLEAR = 2 
 345  BFN_REQUEST = 3 
 346   
 347  INST_ALWAYS_ON = 128 
 348   
 349  # Bit flags for IS_BTN BStyle. 
 350  ISB_C1 = 1 
 351  ISB_C2 = 2 
 352  ISB_C4 = 4 
 353  ISB_CLICK = 8 
 354  ISB_LIGHT = 16 
 355  ISB_DARK = 32 
 356  ISB_LEFT = 64 
 357  ISB_RIGHT = 128 
 358   
 359  # Bit flags for BTN CFlags. 
 360  ISB_LMB = 1 
 361  ISB_RMB = 2 
 362  ISB_CTRL = 4 
 363  ISB_SHIFT = 8 
 364   
 365  # Enum for Weather. 
 366  WEA_BRIGHTCLEAR = 0 
 367  WEA_OVERCAST = 1 
 368  WEA_CLOUDYSUNSETDUSK = 2 
 369   
 370  # Enum for Wind. 
 371  WND_NONE = 0 
 372  WND_LOW = 1 
 373  WND_HIGH = 2 
 374   
 375  # Enum for IS_FLG Flag 
 376  FLG_BLUE = 1 
 377  FLG_YELLOW = 2 
 378   
 379  # Enum for IS_FLG OffOn. 
 380  FLG_ON = 1 
 381  FLG_OFF = 0 
 382   
 383  # Enum for IS_RIP Error. 
 384  RIP_OK = 0 
 385  RIP_ALREADY = 1 
 386  RIP_DEDICATED = 2 
 387  RIP_WRONG_MODE = 3 
 388  RIP_NOT_REPLAY = 4 
 389  RIP_CORRUPTED = 5 
 390  RIP_NOT_FOUND = 6 
 391  RIP_UNLOADABLE = 7 
 392  RIP_DEST_OOB = 8 
 393  RIP_UNKNOWN = 9 
 394  RIP_USER = 10 
 395  RIP_OOS = 11 
 396   
 397  # Enum for IS_RIP Options. 
 398  RIPOPT_LOOP    = 1 
 399  RIPOPT_SKINS = 2 
 400   
 401  # Enum for IS_SSH Error. 
 402  SSH_OK = 0 
 403  SSH_DEDICATED = 1 
 404  SSH_CORRUPTED = 2 
 405  SSH_NO_SAVE = 3 
 406   
 407  # Bit flags for IS_NPL SetF. 
 408  SETF_SYMM_WHEELS = 1 
 409  SETF_TC_ENABLE = 2 
 410  SETF_ABS_ENABLE    = 4 
 411   
 412  # Colour constants. 
 413  COL_BLACK = '^0' 
 414  COL_RED = '^1' 
 415  COL_LIGHT_GREEN = '^2' 
 416  COL_YELLOW = '^3' 
 417  COL_BLUE = '^4' 
 418  COL_PURPLE = '^5' 
 419  COL_LIGHT_BLUE = '^6' 
 420  COL_WHITE = '^7' 
 421  COL_DARK_GREEN = '^8' 
 422  COL_ORIGINAL = '^9' 
 423          
 424  # Bit flags for OutGaugePack Flags.  
 425  OG_TURBO = 8192 
 426  OG_KM = 16384    
 427  OG_BAR = 32768 
 428   
 429  # Bit flags OutGaugePack DashLights and ShowLights 
 430  DL_SHIFT = 1 
 431  DL_FULLBEAM = 2 
 432  DL_HANDBRAKE = 4 
 433  DL_PITSPEED = 8 
 434  DL_TC = 16 
 435  DL_SIGNAL_L = 32 
 436  DL_SIGNAL_R = 64 
 437  DL_SIGNAL_ANY = 128 
 438  DL_OILWARN = 256 
 439  DL_BATTERY = 512 
 440  DL_ABS = 1024 
 441  DL_SPARE = 2048 
 442  DL_NUM= 4096 
 443    
 444  # Functions. 
445 -def checkIP(ipStr):
446 """ 447 Check if a string contains a valid IP address. 448 449 @type ipStr: string 450 @param ipStr: The host IP string to check. 451 452 @rtype: boolean 453 @return: True if the IP is valid. 454 455 """ 456 if ipStr.lower() == 'localhost': 457 return True 458 return re.match(_IP_PATTERN, ipStr)
459 460
461 -def checkPort(portStr):
462 """Check if a string contains a valid port number. 463 464 @type portStr: string 465 @param portStr: The port string to check. 466 467 @rtype: boolean 468 @return: True if the port number is valid. 469 470 """ 471 if portStr.isdigit(): 472 return int(portStr) >= MIN_PORT and int(portStr) <= MAX_PORT 473 return False
474 475
476 -def checkAdmin(adminStr):
477 """Check if a string contains a valid admin password. 478 479 @type adminStr: string 480 @param adminStr: The admin password string to check. 481 482 @rtype: boolean 483 @return: True if the admin password is valid. 484 485 """ 486 return len(adminStr) < ADMIN_LEN
487 488
489 -def parseCommand(mso, prefix):
490 """Parse a command string from an MSO message (EG '!admin DarkTimes') and 491 return it as a tuple. 492 493 @type mso: IS_MSO 494 @param mso: An IS_MSO packet, possibly containing a command. 495 @type prefix: string 496 @param prefix: The prefix (E.G. '!') the command begins with. 497 498 @rtype: tuple 499 @return: A tuple, with the command as the first element, any following 500 command string as the second element, or () if no command could be parsed. 501 502 """ 503 msg = mso.Msg[mso.TextStart:] 504 if msg.startswith(prefix): 505 return msg[1:].split(' ', 1) 506 return ()
507 508
509 -def strToUnicode(str_, default='L', cols=True):
510 """Convert a LFS encoded string to unicode. 511 512 @type str_: string 513 @param str_: The LFS encoded string. 514 @type default: string 515 @param default: The default encoding to start with (E.G. L, G, J etc..). 516 @type cols: boolean 517 @param cols: Whether to keep colour codes in the string. 518 519 @rtype: unicode string 520 @return: The string encoded to unicode. 521 522 """ 523 output = u'' 524 accum = '' 525 codec = _ENCODING_MAP[default] 526 ctrlChar = False 527 for c in str_: 528 if ctrlChar: 529 if c in _ENCODING_MAP: 530 codec = _ENCODING_MAP[c] 531 elif c in _ESCAPE_MAP: 532 accum += _ESCAPE_MAP[c] 533 elif cols: 534 accum += '^' + c 535 ctrlChar = False 536 else: 537 if c == '^': 538 ctrlChar = True 539 output += accum.decode(codec) 540 accum = '' 541 else: 542 accum += c 543 output += accum.decode(codec) 544 return output
545 546
547 -def stripColours(lfsStr):
548 """Strip colour codes (^1, ^3 etc..) from a string. 549 550 @type lfsStr: string 551 @param lfsStr: The string to strip. 552 553 @rtype: string 554 @return: The string sans colour codes. 555 556 """ 557 return re.sub(re.compile('\^[0-9]'), '', lfsStr)
558 559
560 -def speedToMps(speed):
561 """Convert speed to meters per second. 562 563 @type speed: number 564 @param speed: The speed to convert. 565 566 @rtype: number 567 @return: Meters per second. 568 569 """ 570 return speed / 327.68
571 572
573 -def speedToKph(speed):
574 """Convert speed to kilometers per hour. 575 576 @type speed: number 577 @param speed: The speed to convert. 578 579 @rtype: number 580 @return: Kilometers per hour. 581 582 """ 583 return speed / 91.02
584 585
586 -def mpsToKph(mps):
587 """Convert meters per second to kilometers per hour. 588 589 @type mps: number 590 @param mps: Meters per second. 591 592 @rtype: number 593 @return: Kilometers per hour. 594 595 """ 596 return mps * 3.6
597 598
599 -def speedToMph(speed):
600 """Convert speed to miles per hour. 601 602 @type speed: number 603 @param speed: The speed to convert. 604 605 @rtype: number 606 @return: Miles per hour. 607 608 """ 609 return speed / 146.486067
610 611
612 -def mpsToMph(mps):
613 """Convert meters per second to miles per hour. 614 615 @type mps: number 616 @param mps: Meters per second. 617 618 @rtype: number 619 @return: Miles per hour. 620 621 """ 622 return mps * 2.23
623
624 -def metersToMiles(meters):
625 """Convert meters to miles. 626 627 @type meters: number 628 @param meters: The meters to convert. 629 630 @rtype: number 631 @return: Miles. 632 633 """ 634 return meters / 1609.344
635
636 -def metersToKilometers(meters):
637 """Convert meters to kilometers. 638 639 @type meters: number 640 @param meters: The meters to convert. 641 642 @rtype: number 643 @return: Kilometers. 644 645 """ 646 return meters / 1000
647
648 -def directionToDegrees(direction):
649 """Convert direction to degrees. 650 651 @type direction: number 652 @param direction: The direction to convert. 653 654 @rtype: number 655 @return: Degrees. 656 657 """ 658 return direction / 182.04
659
660 -def lengthToMetres(length):
661 """Convert length to meters. 662 663 @type length: number 664 @param length: The length to convert. 665 666 @rtype: number 667 @return: Meters 668 669 """ 670 return length / 65536.0
671 672
673 -def distance(a = (0, 0, 0), b = (0, 0, 0)):
674 """Calculate the distance between two points. 675 676 @type a: tuple 677 @param a: The points (X, Y, Z) coordinates. 678 @type b: tuple 679 @param b: The points (X, Y, Z) coordinates. 680 681 @rtype: number 682 @return: The distance. 683 684 """ 685 return math.sqrt((b[0] - a[0]) * (b[0] - a[0]) + (b[1] - a[1]) * 686 (b[1] - a[1]) + (b[2] - a[2]) * (b[2] - a[2]))
687 688
689 -def radiansToDegrees(radians):
690 """Convert radians to degrees. 691 692 @type radians: number 693 @param radians: The radians to convert. 694 695 @rtype: number 696 @return: Degrees. 697 698 """ 699 return radians * (180.0 / math.pi);
700
701 -def radiansToRpm(radians):
702 """Convert radians to RPM. 703 704 @type radians: number 705 @param radians: The radians to convert. 706 707 @rtype: number 708 @return: RPM. 709 710 """ 711 return radians * (60.0 / (2.0 * math.pi));
712 713 714 # Broken. 715 #def packetXml(packetType, name=None, xmlPath=None, xmlStr=None): 716 # """Create a packet object from XML data. The following is an example of 717 # XML which this function will convert into a Packet object. 718 # 719 # <?xml version="1.0" encoding="utf-8"?> 720 # <pyinsim> 721 # <packet name="init"> 722 # <ReqI>1</ReqI> 723 # <UDPPort>0</UDPPort> 724 # <Admin>pass</Admin> 725 # <IName>Pyinsim</IName> 726 # <Prefix>$</Prefix> 727 # </packet> 728 # </pyinsim> 729 # 730 # In order to create a Packet from this XML data, you would call the function 731 # with the following paramaters. 732 # 733 # isi = pyinsim.packetXml(pyinsim.ISP_ISI, "init", pathToXmlFile) 734 # 735 # Args: 736 # packetType - The packet type from the ISP_* enumeration. 737 # name - The name attribute of the packet in the XML. 738 # xmlPath - A path to an XML file or... 739 # xmlStr - Alternatively a string of XML data. 740 # 741 # Returns: 742 # A packet object populated from the XML data. 743 # 744 # """ 745 # # This function almost feels a little obsolete, it works well, but it 746 # # could be a lot better. 747 # if xmlPath is None: 748 # doc = minidom.parseString(xmlStr) 749 # else: 750 # doc = minidom.parse(xmlPath) 751 # 752 # packet = Packet(packetType) 753 # for baseNode in doc.getElementsByTagName('packet'): 754 # node = str(baseNode.getAttribute('name')) 755 # if node == name: 756 # for attribute in packet.iterkeys(): 757 # for subNode in baseNode.getElementsByTagName(attribute): 758 # data = subNode.firstChild.data 759 # if type(packet[attribute]) == str: 760 # packet[attribute] = str(data) 761 # elif type(packet[attribute ]) == int: 762 # packet[attribute] = int(data) 763 # elif type(packet[attribute ]) == float: 764 # packet[attribute] = float(data) 765 # elif type(packet[attribute ]) == chr: 766 # packet[attribute] = chr(data) 767 # return packet 768 769
770 -def insimConnect(host='localhost', port=29999, **values):
771 """Short-hand for initailising an InSim connection. It creates an 772 Insim object, calls its connect() method, and sends an ISI packet. 773 774 >>> # Example. 775 >>> insim = pyinsim.insimConnect('localhost', 29999, Admin='pass') 776 777 @type host: string 778 @param host: The host to connect to. 779 @type port: number 780 @param port: The port to connect to the host through. 781 @type values: args 782 @param values: The values to initailise the ISI packet with. 783 784 @rtype: InSim 785 @return: The initailised InSim object. 786 787 """ 788 insim = InSim() 789 insim.connect(host, port) 790 insim.send(ISP_ISI, **values) 791 return insim
792
793 -def startOutReceiver(host='localhost', port=30000, mode=OUT_INSIM, timeout=10.0):
794 """Short-hand for initailising an OutReceiver(). 795 796 @type host: string 797 @param host: The host to connect to. 798 @type port: number 799 @param port: The port to connect to the host through. 800 @type mode: enum 801 @param mode: The mode from the OUT_ enumeration. 802 @type timeout: number 803 @param timeout: The seconds to wait before timing out. 804 805 @rtype: OutReceiver 806 @return: The initailise OutReceiver object. 807 808 """ 809 out = OutReceiver(mode, timeout) 810 out.start(host, port) 811 return out
812
813 -def time(ms):
814 """Convert milliseconds into hours, minutes, seconds and thousanths. 815 816 @type ms: number 817 @param ms: The time in milliseconds 818 819 @rtype: tuple 820 @return: A tuple containing the (hours, mins, secs, thousandths). 821 822 """ 823 h = int(math.floor(ms / 3600000)) 824 m = int(math.floor(ms / 1000 / 60) % 60) 825 s = int(math.floor(ms / 1000) % 60) 826 t = int(ms % 1000) 827 return (h, m, s, t)
828
829 -def timeStr(ms, hours=False):
830 """Convert milliseconds into a formatted time string (EG h:m:s.t). 831 832 @type ms: number 833 @param ms: The time in milliseconds. 834 @type hours: boolean 835 @param hours: Set to True to force use of the hours componant of the time. 836 837 @rtype: string 838 @return: The formatted time string (E.G. hh:mm:ss.ttt) 839 840 """ 841 h, m, s, t = time(ms) 842 if h or hours: 843 return '%d.%.2d:%.2d.%.3d' % (h, m, s, t) 844 else: 845 return '%d:%.2d.%.3d' % (m, s, t)
846 847 848 # Helper functions.
849 -def _packetSize(data):
850 """Get the size of the packet.""" 851 if len(data): 852 return ord(data[0]) 853 return 0
854
855 -def _packetType(data):
856 """Get the packet type from the ISP_ enumeration.""" 857 if len(data): 858 return ord(data[1]) 859 return ISP_NONE
860
861 -def _tinyType(data):
862 """Get the tiny type from the TINY_ enumeration.""" 863 return ord(data[3])
864
865 -def _eatNullChars(str_):
866 """Remove NULL terminating line characters.""" 867 return str_.rstrip('\000')
868 869 870 # InSim packets.
871 -class IS_ISI:
872 """InSim Init - packet to initialise the InSim system 873 874 """
875 - def __init__(self, ReqI=0, UDPPort=0, Flags=0, Prefix=' ', Interval=0, Admin='', IName=''):
876 """Initialise the packet. 877 878 @type ReqI: number 879 @param ReqI: If non-zero LFS will send an IS_VER packet 880 @type UDPPort: number 881 @param UDPPort: Port for UDP replies from LFS (0 to 65535) 882 @type Flags: number 883 @param Flags: ISF_ bit flags for options 884 @type Prefix: string 885 @param Prefix: Special host message prefix character 886 @type Interval: number 887 @param Interval: Time in ms between NLP or MCI (0 = none) 888 @type Admin: string 889 @param Admin: Admin password (if set in LFS) 890 @type IName: string 891 @param IName: A short name for your program 892 893 """ 894 self.Size = 44 895 self.Type = ISP_ISI 896 self.ReqI = ReqI 897 self.Zero = 0 898 self.UDPPort = UDPPort 899 self.Flags = Flags 900 self.Sp0 = 0 901 self.Prefix = Prefix 902 self.Interval = Interval 903 self.Admin = Admin 904 self.IName = IName
905
906 - def pack(self):
907 """Pack the packet values into a binary formatted string. 908 909 @rtype: string 910 @return: A binary formatted string. 911 912 """ 913 return struct.pack('BBBBHHBcH16s16s', self.Size, self.Type, self.ReqI, self.Zero, self.UDPPort, self.Flags, self.Sp0, self.Prefix, self.Interval, self.Admin, self.IName)
914
915 - def unpack(self, data):
916 """Unpack the packet data from a binary formatted string. 917 918 @type data: string 919 @param data: The packet data as a binary formatted string. 920 921 """ 922 self.Size, self.Type, self.ReqI, self.Zero, self.UDPPort, self.Flags, self.Sp0, self.Prefix, self.Interval, self.Admin, self.IName = struct.unpack('BBBBHHBcH16s16s', data) 923 self.Admin = _eatNullChars(self.Admin) 924 self.IName = _eatNullChars(self.IName)
925 926
927 -class IS_VER:
928 """VERsion. It is advisable to request version information as soon as you 929 have connected, to avoid problems when connecting to a host with a later or 930 earlier version. You will be sent a version packet on connection if you 931 set ReqI in the IS_ISI packet. 932 933 """
934 - def __init__(self, ReqI=0, Version='', Product='', InSimVer=0):
935 """Initialise the packet. 936 937 @type ReqI: number 938 @param ReqI: ReqI as received in the request packet 939 @type Version: string 940 @param Version: LFS version, e.g. 0.3G 941 @type Product: string 942 @param Product: Product : DEMO or S1 943 @type InSimVer: number 944 @param InSimVer: InSim Version : increased when InSim packets change 945 946 """ 947 self.Size = 20 948 self.Type = ISP_VER 949 self.ReqI = ReqI 950 self.Zero = 0 951 self.Version = Version 952 self.Product = Product 953 self.InSimVer = InSimVer
954
955 - def pack(self):
956 """Pack the packet values into a binary formatted string. 957 958 @rtype: string 959 @return: A binary formatted string. 960 961 """ 962 return struct.pack('BBBB8s6sH', self.Size, self.Type, self.ReqI, self.Zero, self.Version, self.Product, self.InSimVer)
963
964 - def unpack(self, data):
965 """Unpack the packet data from a binary formatted string. 966 967 @type data: string 968 @param data: The packet data as a binary formatted string. 969 970 """ 971 self.Size, self.Type, self.ReqI, self.Zero, self.Version, self.Product, self.InSimVer = struct.unpack('BBBB8s6sH', data) 972 self.Version = _eatNullChars(self.Version) 973 self.Product = _eatNullChars(self.Product)
974 975
976 -class IS_TINY:
977 """General purpose packet. 978 979 """
980 - def __init__(self, ReqI=0, SubT=0):
981 """Initialise the packet. 982 983 @type ReqI: number 984 @param ReqI: zero (0) unless in response to a request. 985 @type SubT: enum 986 @param SubT: subtype from TINY_ enumeration (e.g. TINY_REN) 987 988 """ 989 self.Size = 4 990 self.Type = ISP_TINY 991 self.ReqI = ReqI 992 self.SubT = SubT
993
994 - def pack(self):
995 """Pack the packet values into a binary formatted string. 996 997 @rtype: string 998 @return: A binary formatted string. 999 1000 """ 1001 return struct.pack('BBBB', self.Size, self.Type, self.ReqI, self.SubT)
1002
1003 - def unpack(self, data):
1004 """Unpack the packet data from a binary formatted string. 1005 1006 @type data: string 1007 @param data: The packet data as a binary formatted string. 1008 1009 """ 1010 self.Size, self.Type, self.ReqI, self.SubT = struct.unpack('BBBB', data)
1011 1012
1013 -class IS_SMALL:
1014 """General purpose packet. 1015 1016 """
1017 - def __init__(self, ReqI=0, SubT=0, UVal=0):
1018 """Initialise the packet. 1019 1020 @type ReqI: number 1021 @param ReqI: zero (0) unless in response to a request. 1022 @type SubT: enum 1023 @param SubT: subtype from SMALL_ enumeration (e.g. SMALL_SSP) 1024 @type UVal: number 1025 @param UVal: value (e.g. for SMALL_SSP this would be the OutSim packet rate) 1026 1027 """ 1028 self.Size = 8 1029 self.Type = ISP_SMALL 1030 self.ReqI = ReqI 1031 self.SubT = SubT 1032 self.UVal = UVal
1033
1034 - def pack(self):
1035 """Pack the packet values into a binary formatted string. 1036 1037 @rtype: string 1038 @return: A binary formatted string. 1039 1040 """ 1041 return struct.pack('BBBBI', self.Size, self.Type, self.ReqI, self.SubT, self.UVal)
1042
1043 - def unpack(self, data):
1044 """Unpack the packet data from a binary formatted string. 1045 1046 @type data: string 1047 @param data: The packet data as a binary formatted string. 1048 1049 """ 1050 self.Size, self.Type, self.ReqI, self.SubT, self.UVal = struct.unpack('BBBBI', data)
1051 1052
1053 -class IS_STA:
1054 """STAte packet, sent whenever the data in the packet changes. To request 1055 this packet send a TINY with a ReqI of non-zero and a SubT of TINY_STA. 1056 1057 """
1058 - def __init__(self, ReqI=0, ReplaySpeed=0.0, Flags=0, InGameCam=0, ViewPLID=0, NumP=0, NumConns=0, NumFinished=0, RaceInProg=0, QualMins=0, RaceLaps=0, Track='', Weather=0, Wind=0):
1059 """Initialise the packet. 1060 1061 @param ReqI: ReqI if replying to a request packet 1062 @param ReplaySpeed: 4-byte float - 1.0 is normal speed 1063 @param Flags: ISS_ state flags 1064 @param InGameCam: Which type of camera is selected 1065 @param ViewPLID: Unique ID of viewed player (0 = none) 1066 @param NumP: Number of players in race 1067 @param NumConns: Number of connections including host 1068 @param NumFinished: Number finished or qualified 1069 @param RaceInProg: 0 - no race / 1 - race / 2 - qualifying 1070 @param QualMins: Qualifing minutes 1071 @param RaceLaps: see "RaceLaps" near the top of this document 1072 @param Track: short name for track e.g. FE2R 1073 @param Weather: options from WEA_ 1074 @param Wind: options from WND_ 1075 1076 """ 1077 self.Size = 28 1078 self.Type = ISP_STA 1079 self.ReqI = ReqI 1080 self.Zero = 0 1081 self.ReplaySpeed = ReplaySpeed 1082 self.Flags = Flags 1083 self.InGameCam = InGameCam 1084 self.ViewPLID = ViewPLID 1085 self.NumP = NumP 1086 self.NumConns = NumConns 1087 self.NumFinished = NumFinished 1088 self.RaceInProg = RaceInProg 1089 self.QualMins = QualMins 1090 self.RaceLaps = RaceLaps 1091 self.Spare2 = 0 1092 self.Spare3 = 0 1093 self.Track = Track 1094 self.Weather = Weather 1095 self.Wind = Wind
1096
1097 - def pack(self):
1098 """Pack the packet values into a binary formatted string. 1099 1100 @rtype: string 1101 @return: A binary formatted string. 1102 1103 """ 1104 return struct.pack('BBBBfHBBBBBBBBBB6sBB', self.Size, self.Type, self.ReqI, self.Zero, self.ReplaySpeed, self.Flags, self.InGameCam, self.ViewPLID, self.NumP, self.NumConns, self.NumFinished, self.RaceInProg, self.QualMins, self.RaceLaps, self.Spare2, self.Spare3, self.Track, self.Weather, self.Wind)
1105
1106 - def unpack(self, data):
1107 """Unpack the packet data from a binary formatted string. 1108 1109 @type data: string 1110 @param data: The packet data as a binary formatted string. 1111 1112 """ 1113 self.Size, self.Type, self.ReqI, self.Zero, self.ReplaySpeed, self.Flags, self.InGameCam, self.ViewPLID, self.NumP, self.NumConns, self.NumFinished, self.RaceInProg, self.QualMins, self.RaceLaps, self.Spare2, self.Spare3, self.Track, self.Weather, self.Wind = struct.unpack('BBBBfHBBBBBBBBBB6sBB', data) 1114 self.Track = _eatNullChars(self.Track)
1115 1116
1117 -class IS_SCH:
1118 """Single CHaracter 1119 1120 You can send individual key presses to LFS with the IS_SCH packet. For 1121 standard keys (e.g. V and H) you should send a capital letter. This does 1122 not work with some keys like F keys, arrows or CTRL keys. You can also use 1123 IS_MST with the /press /shift /ctrl /alt commands. 1124 1125 """
1126 - def __init__(self, ReqI=0, CharB=0, Flags=0):
1127 """Initialise the packet. 1128 1129 @param ReqI: 0 1130 @param CharB: key to press 1131 @param Flags: bit 0 : SHIFT / bit 1 : CTRL 1132 1133 """ 1134 self.Size = 8 1135 self.Type = ISP_SCH 1136 self.ReqI = ReqI 1137 self.Zero = 0 1138 self.CharB = CharB 1139 self.Flags = Flags 1140 self.Spare2 = 0 1141 self.Spare3 = 0
1142
1143 - def pack(self):
1144 """Pack the packet values into a binary formatted string. 1145 1146 @rtype: string 1147 @return: A binary formatted string. 1148 1149 """ 1150 return struct.pack('BBBBBBBB', self.Size, self.Type, self.ReqI, self.Zero, self.CharB, self.Flags, self.Spare2, self.Spare3)
1151
1152 - def unpack(self, data):
1153 """Unpack the packet data from a binary formatted string. 1154 1155 @type data: string 1156 @param data: The packet data as a binary formatted string. 1157 1158 """ 1159 self.Size, self.Type, self.ReqI, self.Zero, self.CharB, self.Flags, self.Spare2, self.Spare3 = struct.unpack('BBBBBBBB', data)
1160 1161
1162 -class IS_SFP:
1163 """State Flags Pack. Send this packet to set the game state. Other states 1164 must be set by using key-presses or slash commands. 1165 1166 """
1167 - def __init__(self, ReqI=0, Flag=0, OffOn=0):
1168 """Initialise the packet. 1169 1170 @param ReqI: ReqI as received in the request packet 1171 @param Flag: ISS_* state flags 1172 @param OffOn: 0 = off / 1 = on 1173 1174 """ 1175 self.Size = 8 1176 self.Type = ISP_SFP 1177 self.ReqI = ReqI 1178 self.Zero = 0 1179 self.Flag = Flag 1180 self.OffOn = OffOn 1181 self.Sp3 = 0
1182
1183 - def pack(self):
1184 """Pack the packet values into a binary formatted string. 1185 1186 @rtype: string 1187 @return: A binary formatted string. 1188 1189 """ 1190 return struct.pack('BBBBHBB', self.Size, self.Type, self.ReqI, self.Zero, self.Flag, self.OffOn, self.Sp3)
1191
1192 - def unpack(self, data):
1193 """Unpack the packet data from a binary formatted string. 1194 1195 @type data: string 1196 @param data: The packet data as a binary formatted string. 1197 1198 """ 1199 self.Size, self.Type, self.ReqI, self.Zero, self.Flag, self.OffOn, self.Sp3 = struct.unpack('BBBBHBB', data)
1200 1201
1202 -class IS_SCC:
1203 """Set Car Camera - Simplified camera packet (not SHIFT+U mode) 1204 1205 """
1206 - def __init__(self, ReqI=0, ViewPLID=0, InGameCam=0):
1207 """Initialise the packet. 1208 1209 @param ReqI: 0 1210 @param ViewPLID: UniqueID of player to view 1211 @param InGameCam: InGameCam (as reported in StatePack) 1212 1213 """ 1214 self.Size = 8 1215 self.Type = ISP_SCC 1216 self.ReqI = ReqI 1217 self.Zero = 0 1218 self.ViewPLID = ViewPLID 1219 self.InGameCam = InGameCam 1220 self.Sp2 = 0 1221 self.Sp3 = 0
1222
1223 - def pack(self):
1224 """Pack the packet values into a binary formatted string. 1225 1226 @rtype: string 1227 @return: A binary formatted string. 1228 1229 """ 1230 return struct.pack('BBBBBBBB', self.Size, self.Type, self.ReqI, self.Zero, self.ViewPLID, self.InGameCam, self.Sp2, self.Sp3)
1231
1232 - def unpack(self, data):
1233 """Unpack the packet data from a binary formatted string. 1234 1235 @type data: string 1236 @param data: The packet data as a binary formatted string. 1237 1238 """ 1239 self.Size, self.Type, self.ReqI, self.Zero, self.ViewPLID, self.InGameCam, self.Sp2, self.Sp3 = struct.unpack('BBBBBBBB', data)
1240 1241
1242 -class IS_CPP:
1243 """Cam Pos Pack - Full camera packet (in car or SHIFT+U mode) 1244 1245 """
1246 - def __init__(self, ReqI=0, Pos=[0, 0, 0], H=0, P=0, R=0, ViewPLID=0, InGameCam=0, FOV=0.0, Time=0, Flags=0):
1247 """Initialise the packet. 1248 1249 @param ReqI: instruction : 0 / or reply : ReqI as received in the TINY_SCP 1250 @param Pos: Position vector 1251 @param H: heading - 0 points along Y axis 1252 @param P: pitch - 0 means looking at horizon 1253 @param R: roll - 0 means no roll 1254 @param ViewPLID: Unique ID of viewed player (0 = none) 1255 @param InGameCam: InGameCam (as reported in StatePack) 1256 @param FOV: FOV in degrees 1257 @param Time: Time to get there (0 means instant + reset) 1258 @param Flags: state flags from ISS_ 1259 1260 """ 1261 self.Size = 32 1262 self.Type = ISP_CPP 1263 self.ReqI = ReqI 1264 self.Zero = 0 1265 self.Pos = Pos 1266 self.H = H 1267 self.P = P 1268 self.R = R 1269 self.ViewPLID = ViewPLID 1270 self.InGameCam = InGameCam 1271 self.FOV = FOV 1272 self.Time = Time 1273 self.Flags = Flags
1274
1275 - def pack(self):
1276 """Pack the packet values into a binary formatted string. 1277 1278 @rtype: string 1279 @return: A binary formatted string. 1280 1281 """ 1282 return struct.pack('BBBBiiiHHHBBfHH', self.Size, self.Type, self.ReqI, self.Zero, self.Pos[0], self.Pos[1], self.Pos[2], self.H, self.P, self.R, self.ViewPLID, self.InGameCam, self.FOV, self.Time, self.Flags)
1283
1284 - def unpack(self, data):
1285 """Unpack the packet data from a binary formatted string. 1286 1287 @type data: string 1288 @param data: The packet data as a binary formatted string. 1289 1290 """ 1291 self.Size, self.Type, self.ReqI, self.Zero, self.Pos[0], self.Pos[1], self.Pos[2], self.H, self.P, self.R, self.ViewPLID, self.InGameCam, self.FOV, self.Time, self.Flags = struct.unpack('BBBBiiiHHHBBfHH', data)
1292 1293
1294 -class IS_ISM:
1295 """InSim Multi 1296 1297 LFS will send this packet when a host is started or joined. 1298 1299 """
1300 - def __init__(self, ReqI=0, Host=0, HName=''):
1301 """Initialise the packet. 1302 1303 @param ReqI: usually 0 / or if a reply : ReqI as received in the TINY_ISM 1304 @param Host: 0 = guest / 1 = host 1305 @param HName: the name of the host joined or started 1306 1307 """ 1308 self.Size = 40 1309 self.Type = ISP_ISM 1310 self.ReqI = ReqI 1311 self.Zero = 0 1312 self.Host = Host 1313 self.Sp1 = 0 1314 self.Sp2 = 0 1315 self.Sp3 = 0 1316 self.HName = HName
1317
1318 - def pack(self):
1319 """Pack the packet values into a binary formatted string. 1320 1321 @rtype: string 1322 @return: A binary formatted string. 1323 1324 """ 1325 return struct.pack('BBBBBBBB32s', self.Size, self.Type, self.ReqI, self.Zero, self.Host, self.Sp1, self.Sp2, self.Sp3, self.HName)
1326
1327 - def unpack(self, data):
1328 """Unpack the packet data from a binary formatted string. 1329 1330 @type data: string 1331 @param data: The packet data as a binary formatted string. 1332 1333 """ 1334 self.Size, self.Type, self.ReqI, self.Zero, self.Host, self.Sp1, self.Sp2, self.Sp3, self.HName = struct.unpack('BBBBBBBB32s', data) 1335 self.HName = _eatNullChars(self.HName)
1336 1337
1338 -class IS_MSO:
1339 """MSg Out - system messages and user messages 1340 1341 """
1342 - def __init__(self, ReqI=0, UCID=0, PLID=0, UserType=0, TextStart=0, Msg=''):
1343 """Initialise the packet. 1344 1345 @param ReqI: 0 1346 @param UCID: connection's unique id (0 = host) 1347 @param PLID: player's unique id (if zero, use UCID) 1348 @param UserType: flags from MSO_ enumeration 1349 @param TextStart: first character of the actual text (after player name) 1350 @param Msg: message 1351 1352 """ 1353 self.Size = 136 1354 self.Type = ISP_MSO 1355 self.ReqI = ReqI 1356 self.Zero = 0 1357 self.UCID = UCID 1358 self.PLID = PLID 1359 self.UserType = UserType 1360 self.TextStart = TextStart 1361 self.Msg = Msg
1362
1363 - def pack(self):
1364 """Pack the packet values into a binary formatted string. 1365 1366 @rtype: string 1367 @return: A binary formatted string. 1368 1369 """ 1370 return struct.pack('BBBBBBBB128s', self.Size, self.Type, self.ReqI, self.Zero, self.UCID, self.PLID, self.UserType, self.TextStart, self.Msg)
1371
1372 - def unpack(self, data):
1373 """Unpack the packet data from a binary formatted string. 1374 1375 @type data: string 1376 @param data: The packet data as a binary formatted string. 1377 1378 """ 1379 self.Size, self.Type, self.ReqI, self.Zero, self.UCID, self.PLID, self.UserType, self.TextStart, self.Msg = struct.unpack('BBBBBBBB128s', data) 1380 self.Msg = _eatNullChars(self.Msg)
1381 1382
1383 -class IS_III:
1384 """InsIm Info - /i message from user to host's InSim 1385 1386 """
1387 - def __init__(self, ReqI=0, UCID=0, PLID=0, Msg=''):
1388 """Initialise the packet. 1389 1390 @param ReqI: 0 1391 @param UCID: connection's unique id (0 = host) 1392 @param PLID: player's unique id (if zero, use UCID) 1393 @param Msg: message 1394 1395 """ 1396 self.Size = 72 1397 self.Type = ISP_III 1398 self.ReqI = ReqI 1399 self.Zero = 0 1400 self.UCID = UCID 1401 self.PLID = PLID 1402 self.Sp2 = 0 1403 self.Sp3 = 0 1404 self.Msg = Msg
1405
1406 - def pack(self):
1407 """Pack the packet values into a binary formatted string. 1408 1409 @rtype: string 1410 @return: A binary formatted string. 1411 1412 """ 1413 return struct.pack('BBBBBBBB64s', self.Size, self.Type, self.ReqI, self.Zero, self.UCID, self.PLID, self.Sp2, self.Sp3, self.Msg)
1414
1415 - def unpack(self, data):
1416 """Unpack the packet data from a binary formatted string. 1417 1418 @type data: string 1419 @param data: The packet data as a binary formatted string. 1420 1421 """ 1422 self.Size, self.Type, self.ReqI, self.Zero, self.UCID, self.PLID, self.Sp2, self.Sp3, self.Msg = struct.unpack('BBBBBBBB64s', data) 1423 self.Msg = _eatNullChars(self.Msg)
1424 1425
1426 -class IS_MST:
1427 """MSg Type - send to LFS to type message or command 1428 1429 """
1430 - def __init__(self, ReqI=0, Msg=''):
1431 """Initialise the packet. 1432 1433 @param ReqI: 0 1434 @param Msg: message (64 characters) 1435 1436 """ 1437 self.Size = 68 1438 self.Type = ISP_MST 1439 self.ReqI = ReqI 1440 self.Zero = 0 1441 self.Msg = Msg
1442
1443 - def pack(self):
1444 """Pack the packet values into a binary formatted string. 1445 1446 @rtype: string 1447 @return: A binary formatted string. 1448 1449 """ 1450 return struct.pack('BBBB64s', self.Size, self.Type, self.ReqI, self.Zero, self.Msg)
1451
1452 - def unpack(self, data):
1453 """Unpack the packet data from a binary formatted string. 1454 1455 @type data: string 1456 @param data: The packet data as a binary formatted string. 1457 1458 """ 1459 self.Size, self.Type, self.ReqI, self.Zero, self.Msg = struct.unpack('BBBB64s', data) 1460 self.Msg = _eatNullChars(self.Msg)
1461 1462
1463 -class IS_MTC:
1464 """Msg To Connection - hosts only - send to a connection or a player 1465 1466 """
1467 - def __init__(self, ReqI=0, UCID=0, PLID=0, Msg=''):
1468 """Initialise the packet. 1469 1470 @param ReqI: 0 1471 @param UCID: connection's unique id (0 = host) 1472 @param PLID: player's unique id (if zero, use UCID) 1473 @param Msg: Message (64 characters) 1474 1475 """ 1476 self.Size = 72 1477 self.Type = ISP_MTC 1478 self.ReqI = ReqI 1479 self.Zero = 0 1480 self.UCID = UCID 1481 self.PLID = PLID 1482 self.Sp2 = 0 1483 self.Sp3 = 0 1484 self.Msg = Msg
1485
1486 - def pack(self):
1487 """Pack the packet values into a binary formatted string. 1488 1489 @rtype: string 1490 @return: A binary formatted string. 1491 1492 """ 1493 return struct.pack('BBBBBBBB64s', self.Size, self.Type, self.ReqI, self.Zero, self.UCID, self.PLID, self.Sp2, self.Sp3, self.Msg)
1494
1495 - def unpack(self, data):
1496 """Unpack the packet data from a binary formatted string. 1497 1498 @type data: string 1499 @param data: The packet data as a binary formatted string. 1500 1501 """ 1502 self.Size, self.Type, self.ReqI, self.Zero, self.UCID, self.PLID, self.Sp2, self.Sp3, self.Msg = struct.unpack('BBBBBBBB64s', data) 1503 self.Msg = _eatNullChars(self.Msg)
1504 1505
1506 -class IS_MOD:
1507 """MODe : send to LFS to change screen mode 1508 1509 """
1510 - def __init__(self, ReqI=0, Bits16=0, RR=0, Width=0, Height=0):
1511 """Initialise the packet. 1512 1513 @param ReqI: 0 1514 @param Bits16: set to choose 16-bit 1515 @param RR: refresh rate - zero for default 1516 @param Width: 0 means go to window 1517 @param Height: 0 means go to window 1518 1519 """ 1520 self.Size = 20 1521 self.Type = ISP_MOD 1522 self.ReqI = ReqI 1523 self.Zero = 0 1524 self.Bits16 = Bits16 1525 self.RR = RR 1526 self.Width = Width 1527 self.Height = Height
1528
1529 - def pack(self):
1530 """Pack the packet values into a binary formatted string. 1531 1532 @rtype: string 1533 @return: A binary formatted string. 1534 1535 """ 1536 return struct.pack('BBBBiiii', self.Size, self.Type, self.ReqI, self.Zero, self.Bits16, self.RR, self.Width, self.Height)
1537
1538 - def unpack(self, data):
1539 """Unpack the packet data from a binary formatted string. 1540 1541 @type data: string 1542 @param data: The packet data as a binary formatted string. 1543 1544 """ 1545 self.Size, self.Type, self.ReqI, self.Zero, self.Bits16, self.RR, self.Width, self.Height = struct.unpack('BBBBiiii', data)
1546 1547
1548 -class IS_VTN:
1549 """VoTe Notify 1550 1551 """
1552 - def __init__(self, ReqI=0, UCID=0, Action=0):
1553 """Initialise the packet. 1554 1555 @param ReqI: 0 1556 @param UCID: connection's unique id 1557 @param Action: Vote action from VOTE_ 1558 1559 """ 1560 self.Size = 8 1561 self.Type = ISP_VTN 1562 self.ReqI = ReqI 1563 self.Zero = 0 1564 self.UCID = UCID 1565 self.Action = Action 1566 self.Spare2 = 0 1567 self.Spare3 = 0
1568
1569 - def pack(self):
1570 """Pack the packet values into a binary formatted string. 1571 1572 @rtype: string 1573 @return: A binary formatted string. 1574 1575 """ 1576 return struct.pack('BBBBBBBB', self.Size, self.Type, self.ReqI, self.Zero, self.UCID, self.Action, self.Spare2, self.Spare3)
1577
1578 - def unpack(self, data):
1579 """Unpack the packet data from a binary formatted string. 1580 1581 @type data: string 1582 @param data: The packet data as a binary formatted string. 1583 1584 """ 1585 self.Size, self.Type, self.ReqI, self.Zero, self.UCID, self.Action, self.Spare2, self.Spare3 = struct.unpack('BBBBBBBB', data)
1586 1587
1588 -class IS_RST:
1589 """Race STart 1590 1591 """
1592 - def __init__(self, ReqI=0, RaceLaps=0, QualMins=0, NumP=0, Track='', Weather=0, Wind=0, Flags=0, NumNodes=0, Finish=0, Split1=0, Split2=0, Split3=0):
1593 """Initialise the packet. 1594 1595 @param ReqI: 0 unless this is a reply to an TINY_RST request 1596 @param RaceLaps: 0 if qualifying 1597 @param QualMins: 0 if race 1598 @param NumP: number of players in race 1599 @param Track: short track name 1600 @param Weather: weather 1601 @param Wind: wind 1602 @param Flags: race flags from HOSTF_ 1603 @param NumNodes: total number of nodes in the path 1604 @param Finish: node index - finish line 1605 @param Split1: node index - split 1 1606 @param Split2: node index - split 2 1607 @param Split3: node index - split 3 1608 1609 """ 1610 self.Size = 28 1611 self.Type = ISP_RST 1612 self.ReqI = ReqI 1613 self.Zero = 0 1614 self.RaceLaps = RaceLaps 1615 self.QualMins = QualMins 1616 self.NumP = NumP 1617 self.Spare = 0 1618 self.Track = Track 1619 self.Weather = Weather 1620 self.Wind = Wind 1621 self.Flags = Flags 1622 self.NumNodes = NumNodes 1623 self.Finish = Finish 1624 self.Split1 = Split1 1625 self.Split2 = Split2 1626 self.Split3 = Split3
1627
1628 - def pack(self):
1629 """Pack the packet values into a binary formatted string. 1630 1631 @rtype: string 1632 @return: A binary formatted string. 1633 1634 """ 1635 return struct.pack('BBBBBBBB6sBBHHHHHH', self.Size, self.Type, self.ReqI, self.Zero, self.RaceLaps, self.QualMins, self.NumP, self.Spare, self.Track, self.Weather, self.Wind, self.Flags, self.NumNodes, self.Finish, self.Split1, self.Split2, self.Split3)
1636
1637 - def unpack(self, data):
1638 """Unpack the packet data from a binary formatted string. 1639 1640 @type data: string 1641 @param data: The packet data as a binary formatted string. 1642 1643 """ 1644 self.Size, self.Type, self.ReqI, self.Zero, self.RaceLaps, self.QualMins, self.NumP, self.Spare, self.Track, self.Weather, self.Wind, self.Flags, self.NumNodes, self.Finish, self.Split1, self.Split2, self.Split3 = struct.unpack('BBBBBBBB6sBBHHHHHH', data) 1645 self.Track = _eatNullChars(self.Track)
1646 1647
1648 -class IS_NCN:
1649 """New ConN 1650 1651 """
1652 - def __init__(self, ReqI=0, UCID=0, UName='', PName='', Admin=0, Total=0, Flags=0):
1653 """Initialise the packet. 1654 1655 @param ReqI: 0 unless this is a reply to a TINY_NCN request 1656 @param UCID: new connection's unique id (0 = host) 1657 @param UName: username 1658 @param PName: nickname 1659 @param Admin: 1 if admin 1660 @param Total: number of connections including host 1661 @param Flags: bit 2 : remote 1662 1663 """ 1664 self.Size = 56 1665 self.Type = ISP_NCN 1666 self.ReqI = ReqI 1667 self.UCID = UCID 1668 self.UName = UName 1669 self.PName = PName 1670 self.Admin = Admin 1671 self.Total = Total 1672 self.Flags = Flags 1673 self.Sp3 = 0
1674
1675 - def pack(self):
1676 """Pack the packet values into a binary formatted string. 1677 1678 @rtype: string 1679 @return: A binary formatted string. 1680 1681 """ 1682 return struct.pack('BBBB24s24sBBBB', self.Size, self.Type, self.ReqI, self.UCID, self.UName, self.PName, self.Admin, self.Total, self.Flags, self.Sp3)
1683
1684 - def unpack(self, data):
1685 """Unpack the packet data from a binary formatted string. 1686 1687 @type data: string 1688 @param data: The packet data as a binary formatted string. 1689 1690 """ 1691 self.Size, self.Type, self.ReqI, self.UCID, self.UName, self.PName, self.Admin, self.Total, self.Flags, self.Sp3 = struct.unpack('BBBB24s24sBBBB', data) 1692 self.UName = _eatNullChars(self.UName) 1693 self.PName = _eatNullChars(self.PName)
1694 1695
1696 -class IS_CNL:
1697 """ConN Leave 1698 1699 """
1700 - def __init__(self, ReqI=0, UCID=0, Reason=0, Total=0):
1701 """Initialise the packet. 1702 1703 @param ReqI: 0 1704 @param UCID: unique id of the connection which left 1705 @param Reason: leave reason from LEAVR_ 1706 @param Total: number of connections including host 1707 1708 """ 1709 self.Size = 8 1710 self.Type = ISP_CNL 1711 self.ReqI = ReqI 1712 self.UCID = UCID 1713 self.Reason = Reason 1714 self.Total = Total 1715 self.Sp2 = 0 1716 self.Sp3 = 0
1717
1718 - def pack(self):
1719 """Pack the packet values into a binary formatted string. 1720 1721 @rtype: string 1722 @return: A binary formatted string. 1723 1724 """ 1725 return struct.pack('BBBBBBBB', self.Size, self.Type, self.ReqI, self.UCID, self.Reason, self.Total, self.Sp2, self.Sp3)
1726
1727 - def unpack(self, data):
1728 """Unpack the packet data from a binary formatted string. 1729 1730 @type data: string 1731 @param data: The packet data as a binary formatted string. 1732 1733 """ 1734 self.Size, self.Type, self.ReqI, self.UCID, self.Reason, self.Total, self.Sp2, self.Sp3 = struct.unpack('BBBBBBBB', data)
1735 1736
1737 -class IS_CPR:
1738 """Conn Player Rename 1739 1740 """
1741 - def __init__(self, ReqI=0, UCID=0, PName='', Plate=''):
1742 """Initialise the packet. 1743 1744 @param ReqI: 0 1745 @param UCID: unique id of the connection 1746 @param PName: new name 1747 @param Plate: number plate 1748 1749 """ 1750 self.Size = 36 1751 self.Type = ISP_CPR 1752 self.ReqI = ReqI 1753 self.UCID = UCID 1754 self.PName = PName 1755 self.Plate = Plate
1756
1757 - def pack(self):
1758 """Pack the packet values into a binary formatted string. 1759 1760 @rtype: string 1761 @return: A binary formatted string. 1762 1763 """ 1764 return struct.pack('BBBB24s8s', self.Size, self.Type, self.ReqI, self.UCID, self.PName, self.Plate)
1765
1766 - def unpack(self, data):
1767 """Unpack the packet data from a binary formatted string. 1768 1769 @type data: string 1770 @param data: The packet data as a binary formatted string. 1771 1772 """ 1773 self.Size, self.Type, self.ReqI, self.UCID, self.PName, self.Plate = struct.unpack('BBBB24s8s', data) 1774 self.PName = _eatNullChars(self.PName)
1775 1776
1777 -class IS_NPL:
1778 """New PLayer joining race (if PLID already exists, then leaving pits) 1779 1780 """
1781 - def __init__(self, ReqI=0, PLID=0, UCID=0, PType=0, Flags=0, PName='', Plate='', CName='', SName='', Tyres=[0, 0, 0, 0], H_Mass=0, H_TRes=0, Model=0, Pass=0, Spare=0, SetF=0, NumP=0):
1782 """Initialise the packet. 1783 1784 @param ReqI: 0 unless this is a reply to an TINY_NPL request 1785 @param PLID: player's newly assigned unique id 1786 @param UCID: connection's unique id 1787 @param PType: bit 0 : female / bit 1 : AI / bit 2 : remote 1788 @param Flags: player flags from PIF_ 1789 @param PName: nickname 1790 @param Plate: number plate - NO ZERO AT END! 1791 @param CName: car name 1792 @param SName: skin name - MAX_CAR_TEX_NAME 1793 @param Tyres: compounds 1794 @param H_Mass: added mass (kg) 1795 @param H_TRes: intake restriction 1796 @param Model: driver model 1797 @param Pass: passengers byte 1798 @param SetF: Flags from SETF_ 1799 @param NumP: number in race (same when leaving pits, 1 more if new) 1800 1801 """ 1802 self.Size = 76 1803 self.Type = ISP_NPL 1804 self.ReqI = ReqI 1805 self.PLID = PLID 1806 self.UCID = UCID 1807 self.PType = PType 1808 self.Flags = Flags 1809 self.PName = PName 1810 self.Plate = Plate 1811 self.CName = CName 1812 self.SName = SName 1813 self.Tyres = Tyres 1814 self.H_Mass = H_Mass 1815 self.H_TRes = H_TRes 1816 self.Model = Model 1817 self.Pass = Pass 1818 self.Spare = 0 1819 self.SetF = SetF 1820 self.NumP = NumP 1821 self.Sp2 = 0 1822 self.Sp3 = 0
1823
1824 - def pack(self):
1825 """Pack the packet values into a binary formatted string. 1826 1827 @rtype: string 1828 @return: A binary formatted string. 1829 1830 """ 1831 return struct.pack('BBBBBBH24s8s4s16sBBBBBBBBiBBBB', self.Size, self.Type, self.ReqI, self.PLID, self.UCID, self.PType, self.Flags, self.PName, self.Plate, self.CName, self.SName, self.Tyres[0], self.Tyres[1], self.Tyres[2], self.Tyres[3], self.H_Mass, self.H_TRes, self.Model, self.Pass, self.Spare, self.SetF, self.NumP, self.Sp2, self.Sp3)
1832
1833 - def unpack(self, data):
1834 """Unpack the packet data from a binary formatted string. 1835 1836 @type data: string 1837 @param data: The packet data as a binary formatted string. 1838 1839 """ 1840 self.Size, self.Type, self.ReqI, self.PLID, self.UCID, self.PType, self.Flags, self.PName, self.Plate, self.CName, self.SName, self.Tyres[0], self.Tyres[1], self.Tyres[2], self.Tyres[3], self.H_Mass, self.H_TRes, self.Model, self.Pass, self.Spare, self.SetF, self.NumP, self.Sp2, self.Sp3 = struct.unpack('BBBBBBH24s8s4s16sBBBBBBBBiBBBB', data) 1841 self.PName = _eatNullChars(self.PName) 1842 self.CName = _eatNullChars(self.CName) 1843 self.SName = _eatNullChars(self.SName)
1844 1845
1846 -class IS_PLP:
1847 """PLayer Pits (go to settings - stays in player list) 1848 1849 """
1850 - def __init__(self, ReqI=0, PLID=0):
1851 """Initialise the packet. 1852 1853 @param ReqI: 0 1854 @param PLID: player's unique id 1855 1856 """ 1857 self.Size = 4 1858 self.Type = ISP_PLP 1859 self.ReqI = ReqI 1860 self.PLID = PLID
1861
1862 - def pack(self):
1863 """Pack the packet values into a binary formatted string. 1864 1865 @rtype: string 1866 @return: A binary formatted string. 1867 1868 """ 1869 return struct.pack('BBBB', self.Size, self.Type, self.ReqI, self.PLID)
1870
1871 - def unpack(self, data):
1872 """Unpack the packet data from a binary formatted string. 1873 1874 @type data: string 1875 @param data: The packet data as a binary formatted string. 1876 1877 """ 1878 self.Size, self.Type, self.ReqI, self.PLID = struct.unpack('BBBB', data)
1879 1880
1881 -class IS_PLL:
1882 """PLayer Leave race (spectate - removed from player list) 1883 1884 """
1885 - def __init__(self, ReqI=0, PLID=0):
1886 """Initialise the packet. 1887 1888 @param ReqI: 0 1889 @param PLID: player's unique id 1890 1891 """ 1892 self.Size = 4 1893 self.Type = ISP_PLL 1894 self.ReqI = ReqI 1895 self.PLID = PLID
1896
1897 - def pack(self):
1898 """Pack the packet values into a binary formatted string. 1899 1900 @rtype: string 1901 @return: A binary formatted string. 1902 1903 """ 1904 return struct.pack('BBBB', self.Size, self.Type, self.ReqI, self.PLID)
1905
1906 - def unpack(self, data):
1907 """Unpack the packet data from a binary formatted string. 1908 1909 @type data: string 1910 @param data: The packet data as a binary formatted string. 1911 1912 """ 1913 self.Size, self.Type, self.ReqI, self.PLID = struct.unpack('BBBB', data)
1914 1915
1916 -class IS_LAP:
1917 """LAP time 1918 1919 """
1920 - def __init__(self, ReqI=0, PLID=0, LTime=0, ETime=0, LapsDone=0, Flags=0, Penalty=0, NumStops=0):
1921 """Initialise the packet. 1922 1923 @param ReqI: 0 1924 @param PLID: player's unique id 1925 @param LTime: lap time (ms) 1926 @param ETime: total time (ms) 1927 @param LapsDone: laps completed 1928 @param Flags: player flags from PIF_ 1929 @param Penalty: current penalty value from PENALTY_ 1930 @param NumStops: number of pit stops 1931 1932 """ 1933 self.Size = 20 1934 self.Type = ISP_LAP 1935 self.ReqI = ReqI 1936 self.PLID = PLID 1937 self.LTime = LTime 1938 self.ETime = ETime 1939 self.LapsDone = LapsDone 1940 self.Flags = Flags 1941 self.Sp0 = 0 1942 self.Penalty = Penalty 1943 self.NumStops = NumStops 1944 self.Sp3 = 0
1945
1946 - def pack(self):
1947 """Pack the packet values into a binary formatted string. 1948 1949 @rtype: string 1950 @return: A binary formatted string. 1951 1952 """ 1953 return struct.pack('BBBBIIHHBBBB', self.Size, self.Type, self.ReqI, self.PLID, self.LTime, self.ETime, self.LapsDone, self.Flags, self.Sp0, self.Penalty, self.NumStops, self.Sp3)
1954
1955 - def unpack(self, data):
1956 """Unpack the packet data from a binary formatted string. 1957 1958 @type data: string 1959 @param data: The packet data as a binary formatted string. 1960 1961 """ 1962 self.Size, self.Type, self.ReqI, self.PLID, self.LTime, self.ETime, self.LapsDone, self.Flags, self.Sp0, self.Penalty, self.NumStops, self.Sp3 = struct.unpack('BBBBIIHHBBBB', data)
1963 1964
1965 -class IS_SPX:
1966 """SPlit X time 1967 1968 """
1969 - def __init__(self, ReqI=0, PLID=0, STime=0, ETime=0, Split=0, Penalty=0, NumStops=0):
1970 """Initialise the packet. 1971 1972 @param ReqI: 0 1973 @param PLID: player's unique id 1974 @param STime: split time (ms) 1975 @param ETime: total time (ms) 1976 @param Split: split number 1, 2, 3 1977 @param Penalty: current penalty value from PENALTY_ 1978 @param NumStops: number of pit stops 1979 1980 """ 1981 self.Size = 16 1982 self.Type = ISP_SPX 1983 self.ReqI = ReqI 1984 self.PLID = PLID 1985 self.STime = STime 1986 self.ETime = ETime 1987 self.Split = Split 1988 self.Penalty = Penalty 1989 self.NumStops = NumStops 1990 self.Sp3 = 0
1991
1992 - def pack(self):
1993 """Pack the packet values into a binary formatted string. 1994 1995 @rtype: string 1996 @return: A binary formatted string. 1997 1998 """ 1999 return struct.pack('BBBBIIBBBB', self.Size, self.Type, self.ReqI, self.PLID, self.STime, self.ETime, self.Split, self.Penalty, self.NumStops, self.Sp3)
2000
2001 - def unpack(self, data):
2002 """Unpack the packet data from a binary formatted string. 2003 2004 @type data: string 2005 @param data: The packet data as a binary formatted string. 2006 2007 """ 2008 self.Size, self.Type, self.ReqI, self.PLID, self.STime, self.ETime, self.Split, self.Penalty, self.NumStops, self.Sp3 = struct.unpack('BBBBIIBBBB', data)
2009 2010
2011 -class IS_PIT:
2012 """PIT stop (stop at pit garage) 2013 2014 """
2015 - def __init__(self, ReqI=0, PLID=0, LapsDone=0, Flags=0, Penalty=0, NumStops=0, Tyres=[0, 0, 0, 0], Work=0):
2016 """Initialise the packet. 2017 2018 @param ReqI: 0 2019 @param PLID: player's unique id 2020 @param LapsDone: laps completed 2021 @param Flags: player flags from PIF_ 2022 @param Penalty: current penalty value from PENALTY_ 2023 @param NumStops: number of pit stops 2024 @param Tyres: tyres changed from TYRE_ 2025 @param Work: pit work from PSE_ flags 2026 2027 """ 2028 self.Size = 24 2029 self.Type = ISP_PIT 2030 self.ReqI = ReqI 2031 self.PLID = PLID 2032 self.LapsDone = LapsDone 2033 self.Flags = Flags 2034 self.Sp0 = 0 2035 self.Penalty = Penalty 2036 self.NumStops = NumStops 2037 self.Sp3 = 0 2038 self.Tyres = Tyres 2039 self.Work = Work 2040 self.Spare = 0
2041
2042 - def pack(self):
2043 """Pack the packet values into a binary formatted string. 2044 2045 @rtype: string 2046 @return: A binary formatted string. 2047 2048 """ 2049 return struct.pack('BBBBHHBBBBBBBBII', self.Size, self.Type, self.ReqI, self.PLID, self.LapsDone, self.Flags, self.Sp0, self.Penalty, self.NumStops, self.Sp3, self.Tyres[0], self.Tyres[1], self.Tyres[2], self.Tyres[3], self.Work, self.Spare)
2050
2051 - def unpack(self, data):
2052 """Unpack the packet data from a binary formatted string. 2053 2054 @type data: string 2055 @param data: The packet data as a binary formatted string. 2056 2057 """ 2058 self.Size, self.Type, self.ReqI, self.PLID, self.LapsDone, self.Flags, self.Sp0, self.Penalty, self.NumStops, self.Sp3, self.Tyres[0], self.Tyres[1], self.Tyres[2], self.Tyres[3], self.Work, self.Spare = struct.unpack('BBBBHHBBBBBBBBII', data)
2059 2060
2061 -class IS_PSF:
2062 """Pit Stop Finished 2063 2064 """
2065 - def __init__(self, ReqI=0, PLID=0, STime=0):
2066 """Initialise the packet. 2067 2068 @param ReqI: 0 2069 @param PLID: player's unique id 2070 @param STime: stop time (ms) 2071 2072 """ 2073 self.Size = 12 2074 self.Type = ISP_PSF 2075 self.ReqI = ReqI 2076 self.PLID = PLID 2077 self.STime = STime 2078 self.Spare = 0
2079
2080 - def pack(self):
2081 """Pack the packet values into a binary formatted string. 2082 2083 @rtype: string 2084 @return: A binary formatted string. 2085 2086 """ 2087 return struct.pack('BBBBII', self.Size, self.Type, self.ReqI, self.PLID, self.STime, self.Spare)
2088
2089 - def unpack(self, data):
2090 """Unpack the packet data from a binary formatted string. 2091 2092 @type data: string 2093 @param data: The packet data as a binary formatted string. 2094 2095 """ 2096 self.Size, self.Type, self.ReqI, self.PLID, self.STime, self.Spare = struct.unpack('BBBBII', data)
2097 2098
2099 -class IS_PLA:
2100 """Pit LAne 2101 2102 """
2103 - def __init__(self, ReqI=0, PLID=0, Fact=0):
2104 """Initialise the packet. 2105 2106 @param ReqI: 0 2107 @param PLID: player's unique id 2108 @param Fact: pit lane facts from PITLANE_ 2109 2110 """ 2111 self.Size = 8 2112 self.Type = ISP_PLA 2113 self.ReqI = ReqI 2114 self.PLID = PLID 2115 self.Fact = Fact 2116 self.Sp1 = 0 2117 self.Sp2 = 0 2118 self.Sp3 = 0
2119
2120 - def pack(self):
2121 """Pack the packet values into a binary formatted string. 2122 2123 @rtype: string 2124 @return: A binary formatted string. 2125 2126 """ 2127 return struct.pack('BBBBBBBB', self.Size, self.Type, self.ReqI, self.PLID, self.Fact, self.Sp1, self.Sp2, self.Sp3)
2128
2129 - def unpack(self, data):
2130 """Unpack the packet data from a binary formatted string. 2131 2132 @type data: string 2133 @param data: The packet data as a binary formatted string. 2134 2135 """ 2136 self.Size, self.Type, self.ReqI, self.PLID, self.Fact, self.Sp1, self.Sp2, self.Sp3 = struct.unpack('BBBBBBBB', data)
2137 2138
2139 -class IS_CCH:
2140 """Camera CHange 2141 2142 """
2143 - def __init__(self, ReqI=0, PLID=0, Camera=0):
2144 """Initialise the packet. 2145 2146 @param ReqI: 0 2147 @param PLID: player's unique id 2148 @param Camera: view identifier from VIEW_ 2149 2150 """ 2151 self.Size = 8 2152 self.Type = ISP_CCH 2153 self.ReqI = ReqI 2154 self.PLID = PLID 2155 self.Camera = Camera 2156 self.Sp1 = 0 2157 self.Sp2 = 0 2158 self.Sp3 = 0
2159
2160 - def pack(self):
2161 """Pack the packet values into a binary formatted string. 2162 2163 @rtype: string 2164 @return: A binary formatted string. 2165 2166 """ 2167 return struct.pack('BBBBBBBB', self.Size, self.Type, self.ReqI, self.PLID, self.Camera, self.Sp1, self.Sp2, self.Sp3)
2168
2169 - def unpack(self, data):
2170 """Unpack the packet data from a binary formatted string. 2171 2172 @type data: string 2173 @param data: The packet data as a binary formatted string. 2174 2175 """ 2176 self.Size, self.Type, self.ReqI, self.PLID, self.Camera, self.Sp1, self.Sp2, self.Sp3 = struct.unpack('BBBBBBBB', data)
2177 2178
2179 -class IS_PEN:
2180 """PENalty (given or cleared) 2181 2182 """
2183 - def __init__(self, ReqI=0, PLID=0, OldPen=0, NewPen=0, Reason=0):
2184 """Initialise the packet. 2185 2186 @param ReqI: 0 2187 @param PLID: player's unique id 2188 @param OldPen: old penalty value from PENALTY_ 2189 @param NewPen: new penalty value PENALTY_ 2190 @param Reason: penalty reason from PENR_ 2191 2192 """ 2193 self.Size = 8 2194 self.Type = ISP_PEN 2195 self.ReqI = ReqI 2196 self.PLID = PLID 2197 self.OldPen = OldPen 2198 self.NewPen = NewPen 2199 self.Reason = Reason 2200 self.Sp3 = 0
2201
2202 - def pack(self):
2203 """Pack the packet values into a binary formatted string. 2204 2205 @rtype: string 2206 @return: A binary formatted string. 2207 2208 """ 2209 return struct.pack('BBBBBBBB', self.Size, self.Type, self.ReqI, self.PLID, self.OldPen, self.NewPen, self.Reason, self.Sp3)
2210
2211 - def unpack(self, data):
2212 """Unpack the packet data from a binary formatted string. 2213 2214 @type data: string 2215 @param data: The packet data as a binary formatted string. 2216 2217 """ 2218 self.Size, self.Type, self.ReqI, self.PLID, self.OldPen, self.NewPen, self.Reason, self.Sp3 = struct.unpack('BBBBBBBB', data)
2219 2220
2221 -class IS_TOC:
2222 """Take Over Car 2223 2224 """
2225 - def __init__(self, ReqI=0, PLID=0, OldUCID=0, NewUCID=0):
2226 """Initialise the packet. 2227 2228 @param ReqI: 0 2229 @param PLID: player's unique id 2230 @param OldUCID: old connection's unique id 2231 @param NewUCID: new connection's unique id 2232 2233 """ 2234 self.Size = 8 2235 self.Type = ISP_TOC 2236 self.ReqI = ReqI 2237 self.PLID = PLID 2238 self.OldUCID = OldUCID 2239 self.NewUCID = NewUCID 2240 self.Sp2 = 0 2241 self.Sp3 = 0
2242
2243 - def pack(self):
2244 """Pack the packet values into a binary formatted string. 2245 2246 @rtype: string 2247 @return: A binary formatted string. 2248 2249 """ 2250 return struct.pack('BBBBBBBB', self.Size, self.Type, self.ReqI, self.PLID, self.OldUCID, self.NewUCID, self.Sp2, self.Sp3)
2251
2252 - def unpack(self, data):
2253 """Unpack the packet data from a binary formatted string. 2254 2255 @type data: string 2256 @param data: The packet data as a binary formatted string. 2257 2258 """ 2259 self.Size, self.Type, self.ReqI, self.PLID, self.OldUCID, self.NewUCID, self.Sp2, self.Sp3 = struct.unpack('BBBBBBBB', data)
2260 2261
2262 -class IS_FLG:
2263 """FLaG (yellow or blue flag changed) 2264 2265 """
2266 - def __init__(self, ReqI=0, PLID=0, OffOn=0, Flag=0, CarBehind=0):
2267 """Initialise the packet. 2268 2269 @param ReqI: 0 2270 @param PLID: player's unique id 2271 @param OffOn: 0 = off / 1 = on 2272 @param Flag: flag given from FLG_ 2273 @param CarBehind: unique id of obstructed player 2274 2275 """ 2276 self.Size = 8 2277 self.Type = ISP_FLG 2278 self.ReqI = ReqI 2279 self.PLID = PLID 2280 self.OffOn = OffOn 2281 self.Flag = Flag 2282 self.CarBehind = CarBehind 2283 self.Sp3 = 0
2284
2285 - def pack(self):
2286 """Pack the packet values into a binary formatted string. 2287 2288 @rtype: string 2289 @return: A binary formatted string. 2290 2291 """ 2292 return struct.pack('BBBBBBBB', self.Size, self.Type, self.ReqI, self.PLID, self.OffOn, self.Flag, self.CarBehind, self.Sp3)
2293
2294 - def unpack(self, data):
2295 """Unpack the packet data from a binary formatted string. 2296 2297 @type data: string 2298 @param data: The packet data as a binary formatted string. 2299 2300 """ 2301 self.Size, self.Type, self.ReqI, self.PLID, self.OffOn, self.Flag, self.CarBehind, self.Sp3 = struct.unpack('BBBBBBBB', data)
2302 2303
2304 -class IS_PFL:
2305 """Player FLags (help flags changed) 2306 2307 """
2308 - def __init__(self, ReqI=0, PLID=0, Flags=0):
2309 """Initialise the packet. 2310 2311 @param ReqI: 0 2312 @param PLID: player's unique id 2313 @param Flags: player flags from PIF_ 2314 2315 """ 2316 self.Size = 8 2317 self.Type = ISP_PFL 2318 self.ReqI = ReqI 2319 self.PLID = PLID 2320 self.Flags = Flags 2321 self.Spare = 0
2322
2323 - def pack(self):
2324 """Pack the packet values into a binary formatted string. 2325 2326 @rtype: string 2327 @return: A binary formatted string. 2328 2329 """ 2330 return struct.pack('BBBBHH', self.Size, self.Type, self.ReqI, self.PLID, self.Flags, self.Spare)
2331
2332 - def unpack(self, data):
2333 """Unpack the packet data from a binary formatted string. 2334 2335 @type data: string 2336 @param data: The packet data as a binary formatted string. 2337 2338 """ 2339 self.Size, self.Type, self.ReqI, self.PLID, self.Flags, self.Spare = struct.unpack('BBBBHH', data)
2340 2341
2342 -class IS_FIN:
2343 """FINished race notification (not a final result - use IS_RES) 2344 2345 """
2346 - def __init__(self, ReqI=0, PLID=0, TTime=0, BTime=0, NumStops=0, Confirm=0, LapsDone=0, Flags=0):
2347 """Initialise the packet. 2348 2349 @param ReqI: 0 2350 @param PLID: player's unique id (0 = player left before result was sent) 2351 @param TTime: race time (ms) 2352 @param BTime: best lap (ms) 2353 @param NumStops: number of pit stops 2354 @param Confirm: confirmation flags from CONF_ 2355 @param LapsDone: laps completed 2356 @param Flags: player flags from PIF_ 2357 2358 """ 2359 self.Size = 20 2360 self.Type = ISP_FIN 2361 self.ReqI = ReqI 2362 self.PLID = PLID 2363 self.TTime = TTime 2364 self.BTime = BTime 2365 self.SpA = 0 2366 self.NumStops = NumStops 2367 self.Confirm = Confirm 2368 self.SpB = 0 2369 self.LapsDone = LapsDone 2370 self.Flags = Flags
2371
2372 - def pack(self):
2373 """Pack the packet values into a binary formatted string. 2374 2375 @rtype: string 2376 @return: A binary formatted string. 2377 2378 """ 2379 return struct.pack('BBBBIIBBBBHH', self.Size, self.Type, self.ReqI, self.PLID, self.TTime, self.BTime, self.SpA, self.NumStops, self.Confirm, self.SpB, self.LapsDone, self.Flags)
2380
2381 - def unpack(self, data):
2382 """Unpack the packet data from a binary formatted string. 2383 2384 @type data: string 2385 @param data: The packet data as a binary formatted string. 2386 2387 """ 2388 self.Size, self.Type, self.ReqI, self.PLID, self.TTime, self.BTime, self.SpA, self.NumStops, self.Confirm, self.SpB, self.LapsDone, self.Flags = struct.unpack('BBBBIIBBBBHH', data)
2389 2390
2391 -class IS_RES:
2392 """RESult (qualify or confirmed finish) 2393 2394 """
2395 - def __init__(self, ReqI=0, PLID=0, UName='', PName='', Plate='', CName='', TTime=0, BTime=0, NumStops=0, Confirm=0, LapsDone=0, Flags=0, ResultNum=0, NumRes=0, PSeconds=0):
2396 """Initialise the packet. 2397 2398 @param ReqI: 0 unless this is a reply to a TINY_RES request 2399 @param PLID: player's unique id (0 = player left before result was sent) 2400 @param UName: username 2401 @param PName: nickname 2402 @param Plate: number plate - NO ZERO AT END! 2403 @param CName: skin prefix 2404 @param TTime: race time (ms) 2405 @param BTime: best lap (ms) 2406 @param NumStops: number of pit stops 2407 @param Confirm: confirmation flags CONF_ 2408 @param LapsDone: laps completed 2409 @param Flags: player flags from PIF_ 2410 @param ResultNum: finish or qualify pos (0 = win / 255 = not added to table) 2411 @param NumRes: total number of results (qualify doesn't always add a new one) 2412 @param PSeconds: penalty time in seconds (already included in race time) 2413 2414 """ 2415 self.Size = 84 2416 self.Type = ISP_RES 2417 self.ReqI = ReqI 2418 self.PLID = PLID 2419 self.UName = UName 2420 self.PName = PName 2421 self.Plate = Plate 2422 self.CName = CName 2423 self.TTime = TTime 2424 self.BTime = BTime 2425 self.SpA = 0 2426 self.NumStops = NumStops 2427 self.Confirm = Confirm 2428 self.SpB = 0 2429 self.LapsDone = LapsDone 2430 self.Flags = Flags 2431 self.ResultNum = ResultNum 2432 self.NumRes = NumRes 2433 self.PSeconds = PSeconds
2434
2435 - def pack(self):
2436 """Pack the packet values into a binary formatted string. 2437 2438 @rtype: string 2439 @return: A binary formatted string. 2440 2441 """ 2442 return struct.pack('BBBB24s24s8s4sIIBBBBHHBBH', self.Size, self.Type, self.ReqI, self.PLID, self.UName, self.PName, self.Plate, self.CName, self.TTime, self.BTime, self.SpA, self.NumStops, self.Confirm, self.SpB, self.LapsDone, self.Flags, self.ResultNum, self.NumRes, self.PSeconds)
2443
2444 - def unpack(self, data):
2445 """Unpack the packet data from a binary formatted string. 2446 2447 @type data: string 2448 @param data: The packet data as a binary formatted string. 2449 2450 """ 2451 self.Size, self.Type, self.ReqI, self.PLID, self.UName, self.PName, self.Plate, self.CName, self.TTime, self.BTime, self.SpA, self.NumStops, self.Confirm, self.SpB, self.LapsDone, self.Flags, self.ResultNum, self.NumRes, self.PSeconds = struct.unpack('BBBB24s24s8s4sIIBBBBHHBBH', data) 2452 self.UName = _eatNullChars(self.UName) 2453 self.PName = _eatNullChars(self.PName) 2454 self.CName = _eatNullChars(self.CName)
2455 2456
2457 -class IS_REO:
2458 """REOrder (when race restarts after qualifying) 2459 2460 """
2461 - def __init__(self, ReqI=0, NumP=0, PLID=[]):
2462 """Initialise the packet. 2463 2464 @param ReqI: 0 unless this is a reply to an TINY_REO request 2465 @param NumP: number of players in race 2466 @param PLID: all PLIDs in new order 2467 2468 """ 2469 self.Size = 36 2470 self.Type = ISP_REO 2471 self.ReqI = ReqI 2472 self.NumP = NumP 2473 self.PLID = PLID
2474
2475 - def pack(self):
2476 """Pack the packet values into a binary formatted string. 2477 2478 @rtype: string 2479 @return: A binary formatted string. 2480 2481 """ 2482 return struct.pack('BBBB32B', self.Size, self.Type, self.ReqI, self.NumP, *self.PLID)
2483
2484 - def unpack(self, data):
2485 """Unpack the packet data from a binary formatted string. 2486 2487 @type data: string 2488 @param data: The packet data as a binary formatted string. 2489 2490 """ 2491 self.Size, self.Type, self.ReqI, self.NumP = struct.unpack('BBBB', data[:4]) 2492 self.PLID = struct.unpack('32B', data[4:])
2493 2494
2495 -class NodeLap:
2496 """Car info in 6 bytes - there is an array of these in the NLP (below) 2497 2498 """
2499 - def __init__(self, Node=0, Lap=0, PLID=0, Position=0):
2500 """Initialise the packet. 2501 2502 @param Node: current path node 2503 @param Lap: current lap 2504 @param PLID: player's unique id 2505 @param Position: current race position : 0 = unknown, 1 = leader, etc... 2506 2507 """ 2508 self.Node = Node 2509 self.Lap = Lap 2510 self.PLID = PLID 2511 self.Position = Position
2512
2513 - def pack(self):
2514 """Pack the packet values into a binary formatted string. 2515 2516 @rtype: string 2517 @return: A binary formatted string. 2518 2519 """ 2520 return struct.pack('HHBB', self.Node, self.Lap, self.PLID, self.Position)
2521
2522 - def unpack(self, data):
2523 """Unpack the packet data from a binary formatted string. 2524 2525 @type data: string 2526 @param data: The packet data as a binary formatted string. 2527 2528 """ 2529 self.Node, self.Lap, self.PLID, self.Position = struct.unpack('HHBB', data)
2530 2531
2532 -class IS_NLP:
2533 """Node and Lap Packet - variable size 2534 2535 @type NodeLaps: list 2536 @ivar NodeLaps: A list of NodeLap packets. 2537 2538 """
2539 - def __init__(self, ReqI=0, NumP=0):
2540 """Initialise the packet. 2541 2542 @param ReqI: 0 unless this is a reply to an TINY_NLP request 2543 @param NumP: number of players in race 2544 2545 """ 2546 self.Size = 4 2547 self.Type = ISP_NLP 2548 self.ReqI = ReqI 2549 self.NumP = NumP 2550 self.NodeLaps = []
2551
2552 - def pack(self):
2553 """Pack the packet values into a binary formatted string. 2554 2555 @rtype: string 2556 @return: A binary formatted string. 2557 2558 """ 2559 return struct.pack('BBBB', self.Size, self.Type, self.ReqI, self.NumP)
2560
2561 - def unpack(self, data):
2562 """Unpack the packet data from a binary formatted string. 2563 2564 @type data: string 2565 @param data: The packet data as a binary formatted string. 2566 2567 """ 2568 self.Size, self.Type, self.ReqI, self.NumP = struct.unpack('BBBB', data[:4]) 2569 lim = self.Size 2570 if self.NumP % 2 == 1: 2571 lim -= 2 2572 offset = 4 2573 while offset < lim: 2574 nl = NodeLap() 2575 nl.unpack(data[offset:offset + 6]) 2576 self.NodeLaps.append(nl) 2577 offset += 6
2578 2579
2580 -class CompCar:
2581 """Car info in 28 bytes - there is an array of these in the MCI (below) 2582 2583 """
2584 - def __init__(self, Node=0, Lap=0, PLID=0, Position=0, Info=0, X=0, Y=0, Z=0, Speed=0, Direction=0, Heading=0, AngVel=0):
2585 """Initialise the packet. 2586 2587 @param Node: current path node 2588 @param Lap: current lap 2589 @param PLID: player's unique id 2590 @param Position: current race position : 0 = unknown, 1 = leader, etc... 2591 @param Info: flags and other info - see below 2592 @param X: X map (65536 = 1 metre) 2593 @param Y: Y map (65536 = 1 metre) 2594 @param Z: Z alt (65536 = 1 metre) 2595 @param Speed: speed (32768 = 100 m/s) 2596 @param Direction: direction of car's motion : 0 = world y direction, 32768 = 180 deg 2597 @param Heading: direction of forward axis : 0 = world y direction, 32768 = 180 deg 2598 @param AngVel: signed, rate of change of heading : (16384 = 360 deg/s) 2599 2600 """ 2601 self.Node = Node 2602 self.Lap = Lap 2603 self.PLID = PLID 2604 self.Position = Position 2605 self.Info = Info 2606 self.Sp3 = 0 2607 self.X = X 2608 self.Y = Y 2609 self.Z = Z 2610 self.Speed = Speed 2611 self.Direction = Direction 2612 self.Heading = Heading 2613 self.AngVel = AngVel
2614
2615 - def pack(self):
2616 """Pack the packet values into a binary formatted string. 2617 2618 @rtype: string 2619 @return: A binary formatted string. 2620 2621 """ 2622 return struct.pack('HHBBBBiiiHHHh', self.Node, self.Lap, self.PLID, self.Position, self.Info, self.Sp3, self.X, self.Y, self.Z, self.Speed, self.Direction, self.Heading, self.AngVel)
2623
2624 - def unpack(self, data):
2625 """Unpack the packet data from a binary formatted string. 2626 2627 @type data: string 2628 @param data: The packet data as a binary formatted string. 2629 2630 """ 2631 self.Node, self.Lap, self.PLID, self.Position, self.Info, self.Sp3, self.X, self.Y, self.Z, self.Speed, self.Direction, self.Heading, self.AngVel = struct.unpack('HHBBBBiiiHHHh', data)
2632 2633
2634 -class IS_MCI:
2635 """Multi Car Info - if more than 8 in race then more than one of these is sent 2636 2637 @type CompCars: list 2638 @ivar CompCars: A list of CompCar packets. 2639 2640 """
2641 - def __init__(self, ReqI=0, NumC=0):
2642 """Initialise the packet. 2643 2644 @param ReqI: 0 unless this is a reply to an TINY_MCI request 2645 @param NumC: number of valid CompCar structs in this packet 2646 2647 """ 2648 self.Size = 4 2649 self.Type = ISP_MCI 2650 self.ReqI = ReqI 2651 self.NumC = NumC 2652 self.CompCars = []
2653
2654 - def pack(self):
2655 """Pack the packet values into a binary formatted string. 2656 2657 @rtype: string 2658 @return: A binary formatted string. 2659 2660 """ 2661 return struct.pack('BBBB', self.Size, self.Type, self.ReqI, self.NumC)
2662
2663 - def unpack(self, data):
2664 """Unpack the packet data from a binary formatted string. 2665 2666 @type data: string 2667 @param data: The packet data as a binary formatted string. 2668 2669 """ 2670 self.Size, self.Type, self.ReqI, self.NumC = struct.unpack('BBBB', data[:4]) 2671 offset = 4 2672 while offset < self.Size: 2673 cc = CompCar() 2674 cc.unpack(data[offset:offset + 28]) 2675 self.CompCars.append(cc) 2676 offset += 28
2677 2678
2679 -class IS_MSX:
2680 """MSg eXtended - like MST but longer (not for commands) 2681 2682 """
2683 - def __init__(self, ReqI=0, Msg=''):
2684 """Initialise the packet. 2685 2686 @param ReqI: 0 2687 @param Msg: Message (96 characters) 2688 2689 """ 2690 self.Size = 100 2691 self.Type = ISP_MSX 2692 self.ReqI = ReqI 2693 self.Zero = 0 2694 self.Msg = Msg
2695
2696 - def pack(self):
2697 """Pack the packet values into a binary formatted string. 2698 2699 @rtype: string 2700 @return: A binary formatted string. 2701 2702 """ 2703 return struct.pack('BBBB96s', self.Size, self.Type, self.ReqI, self.Zero, self.Msg)
2704
2705 - def unpack(self, data):
2706 """Unpack the packet data from a binary formatted string. 2707 2708 @type data: string 2709 @param data: The packet data as a binary formatted string. 2710 2711 """ 2712 self.Size, self.Type, self.ReqI, self.Zero, self.Msg = struct.unpack('BBBB96s', data) 2713 self.Msg = _eatNullChars(self.Msg)
2714 2715
2716 -class IS_MSL:
2717 """MSg Local - message to appear on local computer only 2718 2719 """
2720 - def __init__(self, ReqI=0, Sound=0, Msg=''):
2721 """Initialise the packet. 2722 2723 @param ReqI: 0 2724 @param Sound: Sound from SND_ enumeration. 2725 @param Msg: Message 2726 2727 """ 2728 self.Size = 132 2729 self.Type = ISP_MSL 2730 self.ReqI = ReqI 2731 self.Sound = Sound 2732 self.Msg = Msg
2733
2734 - def pack(self):
2735 """Pack the packet values into a binary formatted string. 2736 2737 @rtype: string 2738 @return: A binary formatted string. 2739 2740 """ 2741 return struct.pack('BBBB128s', self.Size, self.Type, self.ReqI, self.Sound, self.Msg)
2742
2743 - def unpack(self, data):
2744 """Unpack the packet data from a binary formatted string. 2745 2746 @type data: string 2747 @param data: The packet data as a binary formatted string. 2748 2749 """ 2750 self.Size, self.Type, self.ReqI, self.Sound, self.Msg = struct.unpack('BBBB128s', data) 2751 self.Msg = _eatNullChars(self.Msg)
2752 2753
2754 -class IS_CRS:
2755 """Car ReSet 2756 2757 """
2758 - def __init__(self, ReqI=0, PLID=0):
2759 """Initialise the packet. 2760 2761 @param ReqI: 0 2762 @param PLID: player's unique id 2763 2764 """ 2765 self.Size = 4 2766 self.Type = ISP_CRS 2767 self.ReqI = ReqI 2768 self.PLID = PLID
2769
2770 - def pack(self):
2771 """Pack the packet values into a binary formatted string. 2772 2773 @rtype: string 2774 @return: A binary formatted string. 2775 2776 """ 2777 return struct.pack('BBBB', self.Size, self.Type, self.ReqI, self.PLID)
2778
2779 - def unpack(self, data):
2780 """Unpack the packet data from a binary formatted string. 2781 2782 @type data: string 2783 @param data: The packet data as a binary formatted string. 2784 2785 """ 2786 self.Size, self.Type, self.ReqI, self.PLID = struct.unpack('BBBB', data)
2787 2788
2789 -class IS_BFN:
2790 """Button FunctioN - delete buttons / receive button requests 2791 2792 """
2793 - def __init__(self, ReqI=0, SubT=0, UCID=0, ClickID=0, Inst=0):
2794 """Initialise the packet. 2795 2796 @param ReqI: 0 2797 @param SubT: subtype, from BFN_* enumeration 2798 @param UCID: connection to send to or from (0 = local / 255 = all) 2799 @param ClickID: ID of button to delete (if SubT is BFN_DEL_BTN) 2800 @param Inst: used internally by InSim 2801 2802 """ 2803 self.Size = 8 2804 self.Type = ISP_BFN 2805 self.ReqI = ReqI 2806 self.SubT = SubT 2807 self.UCID = UCID 2808 self.ClickID = ClickID 2809 self.Inst = Inst 2810 self.Sp3 = 0
2811
2812 - def pack(self):
2813 """Pack the packet values into a binary formatted string. 2814 2815 @rtype: string 2816 @return: A binary formatted string. 2817 2818 """ 2819 return struct.pack('BBBBBBBB', self.Size, self.Type, self.ReqI, self.SubT, self.UCID, self.ClickID, self.Inst, self.Sp3)
2820
2821 - def unpack(self, data):
2822 """Unpack the packet data from a binary formatted string. 2823 2824 @type data: string 2825 @param data: The packet data as a binary formatted string. 2826 2827 """ 2828 self.Size, self.Type, self.ReqI, self.SubT, self.UCID, self.ClickID, self.Inst, self.Sp3 = struct.unpack('BBBBBBBB', data)
2829 2830
2831 -class IS_AXI:
2832 """AutoX Info 2833 2834 """
2835 - def __init__(self, ReqI=0, AXStart=0, NumCP=0, NumO=0, LName=''):
2836 """Initialise the packet. 2837 2838 @param ReqI: 0 unless this is a reply to an TINY_AXI request 2839 @param AXStart: autocross start position 2840 @param NumCP: number of checkpoints 2841 @param NumO: number of objects 2842 @param LName: the name of the layout last loaded (if loaded locally) 2843 2844 """ 2845 self.Size = 40 2846 self.Type = ISP_AXI 2847 self.ReqI = ReqI 2848 self.Zero = 0 2849 self.AXStart = AXStart 2850 self.NumCP = NumCP 2851 self.NumO = NumO 2852 self.LName = LName
2853
2854 - def pack(self):
2855 """Pack the packet values into a binary formatted string. 2856 2857 @rtype: string 2858 @return: A binary formatted string. 2859 2860 """ 2861 return struct.pack('BBBBBBH32s', self.Size, self.Type, self.ReqI, self.Zero, self.AXStart, self.NumCP, self.NumO, self.LName)
2862
2863 - def unpack(self, data):
2864 """Unpack the packet data from a binary formatted string. 2865 2866 @type data: string 2867 @param data: The packet data as a binary formatted string. 2868 2869 """ 2870 self.Size, self.Type, self.ReqI, self.Zero, self.AXStart, self.NumCP, self.NumO, self.LName = struct.unpack('BBBBBBH32s', data) 2871 self.LName = _eatNullChars(self.LName)
2872 2873
2874 -class IS_AXO:
2875 """AutoX Object 2876 2877 """
2878 - def __init__(self, ReqI=0, PLID=0):
2879 """Initialise the packet. 2880 2881 @param ReqI: 0 2882 @param PLID: player's unique id 2883 2884 """ 2885 self.Size = 4 2886 self.Type = ISP_AXO 2887 self.ReqI = ReqI 2888 self.PLID = PLID
2889
2890 - def pack(self):
2891 """Pack the packet values into a binary formatted string. 2892 2893 @rtype: string 2894 @return: A binary formatted string. 2895 2896 """ 2897 struct.pack('BBBB', self.Size, self.Type, self.ReqI, self.PLID)
2898
2899 - def unpack(self, data):
2900 """Unpack the packet data from a binary formatted string. 2901 2902 @type data: string 2903 @param data: The packet data as a binary formatted string. 2904 2905 """ 2906 self.Size, self.Type, self.ReqI, self.PLID = struct.unpack('BBBB', data)
2907 2908
2909 -class IS_BTN:
2910 """BuTtoN - button header - followed by 0 to 240 characters 2911 2912 """
2913 - def __init__(self, ReqI=0, UCID=0, ClickID=0, Inst=0, BStyle=0, TypeIn=0, L=0, T=0, W=0, H=0, Text=''):
2914 """Initialise the packet. 2915 2916 @param ReqI: non-zero (returned in IS_BTC and IS_BTT packets) 2917 @param UCID: connection to display the button (0 = local / 255 = all) 2918 @param ClickID: button ID (0 to 239) 2919 @param Inst: some extra flags from INST_ 2920 @param BStyle: button style flags from ISB_ 2921 @param TypeIn: max chars to type in 2922 @param L: left: 0 - 200 2923 @param T: top: 0 - 200 2924 @param W: width: 0 - 200 2925 @param H: height: 0 - 200 2926 @param Text: 0 to 240 characters of text 2927 2928 """ 2929 self.Size = 252 2930 self.Type = ISP_BTN 2931 self.ReqI = ReqI 2932 self.UCID = UCID 2933 self.ClickID = ClickID 2934 self.Inst = Inst 2935 self.BStyle = BStyle 2936 self.TypeIn = TypeIn 2937 self.L = L 2938 self.T = T 2939 self.W = W 2940 self.H = H 2941 self.Text = Text
2942
2943 - def pack(self):
2944 """Pack the packet values into a binary formatted string. 2945 2946 @rtype: string 2947 @return: A binary formatted string. 2948 2949 """ 2950 return struct.pack('BBBBBBBBBBBB240s', self.Size, self.Type, self.ReqI, self.UCID, self.ClickID, self.Inst, self.BStyle, self.TypeIn, self.L, self.T, self.W, self.H, self.Text)
2951
2952 - def unpack(self, data):
2953 """Unpack the packet data from a binary formatted string. 2954 2955 @type data: string 2956 @param data: The packet data as a binary formatted string. 2957 2958 """ 2959 self.Size, self.Type, self.ReqI, self.UCID, self.ClickID, self.Inst, self.BStyle, self.TypeIn, self.L, self.T, self.W, self.H, self.Text = struct.unpack('BBBBBBBBBBBB240s', data) 2960 self.Text = _eatNullChars(self.Text)
2961 2962
2963 -class IS_BTC:
2964 """BuTton Click - sent back when user clicks a button 2965 2966 """
2967 - def __init__(self, ReqI=0, UCID=0, ClickID=0, Inst=0, CFlags=0):
2968 """Initialise the packet. 2969 2970 @param ReqI: ReqI as received in the IS_BTN 2971 @param UCID: connection that clicked the button (zero if local) 2972 @param ClickID: button identifier originally sent in IS_BTN 2973 @param Inst: used internally by InSim 2974 @param CFlags: button click flags from ISB_ 2975 2976 """ 2977 self.Size = 8 2978 self.Type = ISP_BTC 2979 self.ReqI = ReqI 2980 self.UCID = UCID 2981 self.ClickID = ClickID 2982 self.Inst = Inst 2983 self.CFlags = CFlags 2984 self.Sp3 = 0
2985
2986 - def pack(self):
2987 """Pack the packet values into a binary formatted string. 2988 2989 @rtype: string 2990 @return: A binary formatted string. 2991 2992 """ 2993 return struct.pack('BBBBBBBB', self.Size, self.Type, self.ReqI, self.UCID, self.ClickID, self.Inst, self.CFlags, self.Sp3)
2994
2995 - def unpack(self, data):
2996 """Unpack the packet data from a binary formatted string. 2997 2998 @type data: string 2999 @param data: The packet data as a binary formatted string. 3000 3001 """ 3002 self.Size, self.Type, self.ReqI, self.UCID, self.ClickID, self.Inst, self.CFlags, self.Sp3 = struct.unpack('BBBBBBBB', data)
3003 3004
3005 -class IS_BTT:
3006 """BuTton Type - sent back when user types into a text entry button 3007 3008 """
3009 - def __init__(self, ReqI=0, UCID=0, ClickID=0, Inst=0, TypeIn=0, Text=''):
3010 """Initialise the packet. 3011 3012 @param ReqI: ReqI as received in the IS_BTN 3013 @param UCID: connection that typed into the button (zero if local) 3014 @param ClickID: button identifier originally sent in IS_BTN 3015 @param Inst: used internally by InSim 3016 @param TypeIn: from original button specification 3017 @param Text: typed text, zero to TypeIn specified in IS_BTN 3018 3019 """ 3020 self.Size = 104 3021 self.Type = ISP_BTT 3022 self.ReqI = ReqI 3023 self.UCID = UCID 3024 self.ClickID = ClickID 3025 self.Inst = Inst 3026 self.TypeIn = TypeIn 3027 self.Sp3 = 0 3028 self.Text = Text
3029
3030 - def pack(self):
3031 """Pack the packet values into a binary formatted string. 3032 3033 @rtype: string 3034 @return: A binary formatted string. 3035 3036 """ 3037 return struct.pack('BBBBBBBB96s', self.Size, self.Type, self.ReqI, self.UCID, self.ClickID, self.Inst, self.TypeIn, self.Sp3, self.Text)
3038
3039 - def unpack(self, data):
3040 """Unpack the packet data from a binary formatted string. 3041 3042 @type data: string 3043 @param data: The packet data as a binary formatted string. 3044 3045 """ 3046 self.Size, self.Type, self.ReqI, self.UCID, self.ClickID, self.Inst, self.TypeIn, self.Sp3, self.Text = struct.unpack('BBBBBBBB96s', data) 3047 self.Text = _eatNullChars(self.Text)
3048 3049
3050 -class IS_RIP:
3051 """Replay Information Packet 3052 3053 """
3054 - def __init__(self, ReqI=0, Error=0, MPR=0, Paused=0, Options=0, CTime=0, TTime=0, RName=''):
3055 """Initialise the packet. 3056 3057 @param ReqI: request : non-zero / reply : same value returned 3058 @param Error: 0 or 1 = OK / options from RIP_ 3059 @param MPR: 0 = SPR / 1 = MPR 3060 @param Paused: request : pause on arrival / reply : paused state 3061 @param Options: various options from RIPOPT_ 3062 @param CTime: (hundredths) request : destination / reply : position 3063 @param TTime: (hundredths) request : zero / reply : replay length 3064 @param RName: zero or replay name: last byte must be zero 3065 3066 """ 3067 self.Size = 76 3068 self.Type = ISP_RIP 3069 self.ReqI = ReqI 3070 self.Error = Error 3071 self.MPR = MPR 3072 self.Paused = Paused 3073 self.Options = Options 3074 self.Sp3 = 0 3075 self.CTime = CTime 3076 self.TTime = TTime 3077 self.RName = RName
3078
3079 - def pack(self):
3080 """Pack the packet values into a binary formatted string. 3081 3082 @rtype: string 3083 @return: A binary formatted string. 3084 3085 """ 3086 return struct.pack('BBBBBBBBHH64s', self.Size, self.Type, self.ReqI, self.Error, self.MPR, self.Paused, self.Options, self.Sp3, self.CTime, self.TTime, self.RName)
3087
3088 - def unpack(self, data):
3089 """Unpack the packet data from a binary formatted string. 3090 3091 @type data: string 3092 @param data: The packet data as a binary formatted string. 3093 3094 """ 3095 self.Size, self.Type, self.ReqI, self.Error, self.MPR, self.Paused, self.Options, self.Sp3, self.CTime, self.TTime, self.RName = struct.unpack('BBBBBBBBHH64s', data) 3096 self.RName = _eatNullChars(self.RName)
3097 3098
3099 -class IS_SSH:
3100 """ScreenSHot 3101 3102 """
3103 - def __init__(self, ReqI=0, Error=0, BMP=''):
3104 """Initialise the packet. 3105 3106 @param ReqI: request : non-zero / reply : same value returned 3107 @param Error: 0 = OK / other values from SSH_ 3108 @param BMP: name of screenshot file: last byte must be zero 3109 3110 """ 3111 self.Size = 40 3112 self.Type = ISP_SSH 3113 self.ReqI = ReqI 3114 self.Error = Error 3115 self.Sp0 = 0 3116 self.Sp1 = 0 3117 self.Sp2 = 0 3118 self.Sp3 = 0 3119 self.BMP = BMP
3120
3121 - def pack(self):
3122 """Pack the packet values into a binary formatted string. 3123 3124 @rtype: string 3125 @return: A binary formatted string. 3126 3127 """ 3128 return struct.pack('BBBBBBBB32s', self.Size, self.Type, self.ReqI, self.Error, self.Sp0, self.Sp1, self.Sp2, self.Sp3, self.BMP)
3129
3130 - def unpack(self, data):
3131 """Unpack the packet data from a binary formatted string. 3132 3133 @type data: string 3134 @param data: The packet data as a binary formatted string. 3135 3136 """ 3137 self.Size, self.Type, self.ReqI, self.Error, self.Sp0, self.Sp1, self.Sp2, self.Sp3, self.BMP = struct.unpack('BBBBBBBB32s', data) 3138 self.BMP = _eatNullChars(self.BMP)
3139 3140
3141 -class OutSimPack:
3142 """External Motion simulator support 3143 3144 The user's car in multiplayer or the viewed car in single player or 3145 single player replay can output information to a motion system while 3146 viewed from an internal view. 3147 3148 This can be controlled by 5 lines in the cfg.txt file : 3149 3150 >>> OutSim Mode 0 :0-off 1-driving 2-driving+replay 3151 >>> OutSim Delay 1 :minimum delay between packets (100ths of a sec) 3152 >>> OutSim IP 0.0.0.0 :IP address to send the UDP packet 3153 >>> OutSim Port 0 :IP port 3154 >>> OutSim ID 0 :if not zero, adds an identifier to the packet 3155 3156 """
3157 - def __init__(self, Time=0, AngVel=[0.0, 0.0, 0.0], Heading=0.0, Pitch=0.0, Roll=0.0, Accel=[0.0, 0.0, 0.0], Vel=[0.0, 0.0, 0.0], Pos=[0, 0, 0], ID=0):
3158 """ Initailise the packet. 3159 3160 @param Time: time in milliseconds (to check order) 3161 @param AngVel: 3 floats, angular velocity vector 3162 @param Heading: anticlockwise from above (Z) 3163 @param Pitch: anticlockwise from right (X) 3164 @param Roll: anticlockwise from front (Y) 3165 @param Accel: 3 floats X, Y, Z 3166 @param Vel: 3 floats X, Y, Z 3167 @param Pos: 3 ints X, Y, Z (1m = 65536) 3168 @param ID: optional: only if OutSim ID is specified 3169 3170 """ 3171 self.Time = Time 3172 self.AngVel = AngVel 3173 self.Heading = Heading 3174 self.Pitch = Pitch 3175 self.Roll = Roll 3176 self.Accel = Accel 3177 self.Vel = Vel 3178 self.Pos = Pos 3179 self.ID = ID
3180
3181 - def unpack(self, data):
3182 """Unpack the packet data from a binary formatted string. 3183 3184 @type data: string 3185 @param data: The packet data as a binary formatted string. 3186 3187 """ 3188 self.Time, self.AngVel[0], self.AngVel[1], self.AngVel[2], self.Heading, self.Pitch, self.Roll, self.Accel[0], self.Accel[1], self.Accel[2], self.Vel[0], self.Vel[1], self.Vel[2], self.Pos[0], self.Pos[1], self.Pos[2] = struct.unpack('Iffffffffffffiii', data[:64]) 3189 # ID is only on if set in cfg.txt. 3190 if len(data) == 68: 3191 self.ID = struct.unpack('i', data[64:])[0]
3192 3193
3194 -class OutGaugePack:
3195 """External dashboard support. 3196 3197 The user's car in multiplayer or the viewed car in single player or 3198 single player replay can output information to a dashboard system 3199 while viewed from an internal view. 3200 3201 This can be controlled by 5 lines in the cfg.txt file : 3202 3203 >>> OutGauge Mode 0 :0-off 1-driving 2-driving+replay 3204 >>> OutGauge Delay 1 :minimum delay between packets (100ths of a sec) 3205 >>> OutGauge IP 0.0.0.0 :IP address to send the UDP packet 3206 >>> OutGauge Port 0 :IP port 3207 >>> OutGauge ID 0 :if not zero, adds an identifier to the packet 3208 3209 """
3210 - def __init__(self, Time=0, Car='', Flags=0, Gear=0, Speed=0.0, RPM=0.0, Turbo=0.0, EngTemp=0.0, Fuel=0.0, OilPress=0.0, OilTemp=0.0, DashLights=0, ShowLights=0, Throttle=0.0, Brake=0.0, Clutch=0.0, Display1='', Display2='', ID=0):
3211 """Initailise the packet. 3212 3213 @param Time: Time in milliseconds (to check order) 3214 @param Car: Car name 3215 @param Flags: Bit flags from OG_ enumeration 3216 @param Gear: Reverse: 0, Neutral: 1, Firest: 2 etc.. 3217 @param Speed: Meters per second 3218 @param RPM: RPM 3219 @param Turbo: BAR 3220 @param EngTemp: C 3221 @param Fuel: 0.0 to 1.0 3222 @param OilPress: BAR 3223 @param OilTemp: C 3224 @param DashLights: Dash lights available (see DL_x below) 3225 @param ShowLights: Dash lights currently switched on 3226 @param Throttle: 0.0 to 1.0 3227 @param Brake: 0.0 to 1.0 3228 @param Clutch: 0.0 to 1.0 3229 @param Display1: Usually fuel 3230 @param Display2: Usually settings 3231 @param ID: Options, if OutGauge ID specified 3232 3233 """ 3234 self.Time = Time 3235 self.Car = Car 3236 self.Flags = Flags 3237 self.Gear = Gear 3238 self.SpareB = 0 3239 self.Speed = Speed 3240 self.RPM = RPM 3241 self.Turbo = Turbo 3242 self.EngTemp = EngTemp 3243 self.Fuel = Fuel 3244 self.OilPress = OilPress 3245 self.OilTemp = OilTemp 3246 self.DashLights = DashLights 3247 self.ShowLights = ShowLights 3248 self.Throttle = Throttle 3249 self.Brake = Brake 3250 self.Clutch = Clutch 3251 self.Display1 = Display1 3252 self.Display2 = Display2 3253 self.ID = ID
3254
3255 - def unpack(self, data):
3256 """Unpack the packet data from a binary formatted string. 3257 3258 @type data: string 3259 @param data: The packet data as a binary formatted string. 3260 3261 """ 3262 self.Time, self.Car, self.Flags, self.Gear, self.SpareB, self.Speed, self.RPM, self.Turbo, self.EngTemp,self.Fuel, self.OilPress, self.OilTemp, self.DashLights, self.ShowLights, self.Throttle, self.Brake, self.Clutch, self.Display1,self.Display2 = struct.unpack('I4sHBBfffffffIIfff16s16s', data[:92]) 3263 3264 # Check if ID has been set. 3265 if len(data) == 96: 3266 self.ID = struct.unpack('i', data[92:])[0] 3267 self.Car = _eatNullChars(self.Car) 3268 self.Display1 = _eatNullChars(self.Display1) 3269 self.Display2 = _eatNullChars(self.Display2)
3270 3271 3272 # Lookup packet-type from string. 3273 _PACKET_STRS = {'ISP_ISI': ISP_ISI, 3274 'ISP_VER': ISP_VER, 3275 'ISP_TINY': ISP_TINY, 3276 'ISP_SMALL': ISP_SMALL, 3277 'ISP_STA': ISP_STA, 3278 'ISP_SCH': ISP_SCH, 3279 'ISP_SFP': ISP_SFP, 3280 'ISP_SCC': ISP_SCC, 3281 'ISP_CPP': ISP_CPP, 3282 'ISP_ISM': ISP_ISM, 3283 'ISP_MSO': ISP_MSO, 3284 'ISP_III': ISP_III, 3285 'ISP_MST': ISP_MST, 3286 'ISP_MTC': ISP_MTC, 3287 'ISP_MOD': ISP_MOD, 3288 'ISP_VTN': ISP_VTN, 3289 'ISP_RST': ISP_RST, 3290 'ISP_NCN': ISP_NCN, 3291 'ISP_CNL': ISP_CNL, 3292 'ISP_CPR': ISP_CPR, 3293 'ISP_NPL': ISP_NPL, 3294 'ISP_PLP': ISP_PLP, 3295 'ISP_PLL': ISP_PLL, 3296 'ISP_LAP': ISP_LAP, 3297 'ISP_SPX': ISP_SPX, 3298 'ISP_PIT': ISP_PIT, 3299 'ISP_PSF': ISP_PSF, 3300 'ISP_PLA': ISP_PLA, 3301 'ISP_CCH': ISP_CCH, 3302 'ISP_PEN': ISP_PEN, 3303 'ISP_TOC': ISP_TOC, 3304 'ISP_FLG': ISP_FLG, 3305 'ISP_PFL': ISP_PFL, 3306 'ISP_FIN': ISP_FIN, 3307 'ISP_RES': ISP_RES, 3308 'ISP_REO': ISP_REO, 3309 'ISP_NLP': ISP_NLP, 3310 'ISP_MCI': ISP_MCI, 3311 'ISP_MSX': ISP_MSX, 3312 'ISP_MSL': ISP_MSL, 3313 'ISP_CRS': ISP_CRS, 3314 'ISP_BFN': ISP_BFN, 3315 'ISP_AXI': ISP_AXI, 3316 'ISP_AXO': ISP_AXO, 3317 'ISP_BTN': ISP_BTN, 3318 'ISP_BTC': ISP_BTC, 3319 'ISP_BTT': ISP_BTT, 3320 'ISP_RIP': ISP_RIP, 3321 'ISP_SSH': ISP_SSH,} 3322 3323 3324 # Associate packet-types with the packet classes. 3325 _PACKET_DEFS = {ISP_ISI: IS_ISI, 3326 ISP_VER: IS_VER, 3327 ISP_TINY: IS_TINY, 3328 ISP_SMALL: IS_SMALL, 3329 ISP_STA: IS_STA, 3330 ISP_SCH: IS_SCH, 3331 ISP_SFP: IS_SFP, 3332 ISP_SCC: IS_SCC, 3333 ISP_CPP: IS_CPP, 3334 ISP_ISM: IS_ISM, 3335 ISP_MSO: IS_MSO, 3336 ISP_III: IS_III, 3337 ISP_MST: IS_MST, 3338 ISP_MTC: IS_MTC, 3339 ISP_MOD: IS_MOD, 3340 ISP_VTN: IS_VTN, 3341 ISP_RST: IS_RST, 3342 ISP_NCN: IS_NCN, 3343 ISP_CNL: IS_CNL, 3344 ISP_CPR: IS_CPR, 3345 ISP_NPL: IS_NPL, 3346 ISP_PLP: IS_PLP, 3347 ISP_PLL: IS_PLL, 3348 ISP_LAP: IS_LAP, 3349 ISP_SPX: IS_SPX, 3350 ISP_PIT: IS_PIT, 3351 ISP_PSF: IS_PSF, 3352 ISP_PLA: IS_PLA, 3353 ISP_CCH: IS_CCH, 3354 ISP_PEN: IS_PEN, 3355 ISP_TOC: IS_TOC, 3356 ISP_FLG: IS_FLG, 3357 ISP_PFL: IS_PFL, 3358 ISP_FIN: IS_FIN, 3359 ISP_RES: IS_RES, 3360 ISP_REO: IS_REO, 3361 ISP_NLP: IS_NLP, 3362 ISP_MCI: IS_MCI, 3363 ISP_MSX: IS_MSX, 3364 ISP_MSL: IS_MSL, 3365 ISP_CRS: IS_CRS, 3366 ISP_BFN: IS_BFN, 3367 ISP_AXI: IS_AXI, 3368 ISP_AXO: IS_AXO, 3369 ISP_BTN: IS_BTN, 3370 ISP_BTC: IS_BTC, 3371 ISP_BTT: IS_BTT, 3372 ISP_RIP: IS_RIP, 3373 ISP_SSH: IS_SSH,} 3374 3375
3376 -class _Buffer:
3377 """Class to manage the receive buffer. 3378 3379 """
3380 - def __init__(self):
3381 """Initailise the _Buffer() object. 3382 3383 """ 3384 self.__buffer = ''
3385
3386 - def receive(self, data):
3387 """Append received data onto the buffer. 3388 3389 @type data: string 3390 @param data: Binary formatted string. 3391 3392 """ 3393 self.__buffer += data
3394
3395 - def packets(self):
3396 """Get all completed packets currently in the buffer. 3397 3398 @rtype: string 3399 @return: The next completed packet, as a binary formatted string. 3400 3401 """ 3402 size = _packetSize(self.__buffer) 3403 while len(self.__buffer) and len(self.__buffer) >= size: 3404 packet = self.__buffer[:size] 3405 self.__buffer = self.__buffer[size:] 3406 yield packet 3407 size = _packetSize(self.__buffer)
3408 3409
3410 -class InSim:
3411 """Class to manage an InSim connection with LFS. 3412 3413 """
3414 - def __init__(self, conn=INSIM_TCP, timeout=10.0, name='default'):
3415 """Initialise the InSim object. 3416 3417 @type conn: enum 3418 @param conn: Type of connection, either INSIM_TCP or INSIM_UDP. 3419 @type timeout: number 3420 @param timeout: Seconds to wait before timing out in UDP mode. 3421 @type name: string 3422 @param name: An optional name for the connection. 3423 3424 """ 3425 self.__conn = conn 3426 self.__timeout = timeout 3427 self.__name = name 3428 self.__buffer = _Buffer() 3429 self.__connected = False 3430 self.__callbacks = {} 3431 self.__thread = threading.Thread(target=self.__receiveThread) 3432 self.__sock = None
3433
3434 - def getName(self):
3435 """Get the name of the InSim connection. 3436 3437 @rtype: string 3438 @return: Name of the connection. 3439 3440 """ 3441 return self.__name
3442
3443 - def setName(self, name):
3444 """Set the name of the InSim connection. 3445 3446 @type name: string 3447 @param name: Name of the connection. 3448 3449 """ 3450 self.__name = name
3451
3452 - def setTimeout(self, timeout):
3453 """Set the UDP timeout. 3454 3455 @type timeout: number 3456 @param timeout: The timeout seconds. 3457 3458 """ 3459 self.__timeout = timeout
3460
3461 - def getTimeout(self):
3462 """Get the UDP timeout. 3463 3464 @rtype: number 3465 @return: The timeout seconds. 3466 3467 """ 3468 return self.__timeout
3469
3470 - def isConnected(self):
3471 """Get if the socket is connected. 3472 3473 @rtype: boolean 3474 @return: True if the socket is connected. 3475 3476 """ 3477 return self.__connected
3478
3479 - def connect(self, host='localhost', port=29999, blocking=False):
3480 """ 3481 Connect to InSim on the specified host and port. 3482 3483 Known Issues: 3484 In UDP mode no exception is raised if the connection to InSim fails, 3485 but instead an EVT_ERROR is raised after the first packet is sent. 3486 3487 @type host: string 3488 @param host: Host where LFS is running. 3489 @type port: number 3490 @param port: Port to connect to LFS through. 3491 3492 """ 3493 if not self.__connected: 3494 self.__sock = socket.socket(socket.AF_INET, self.__conn) 3495 if self.__conn == INSIM_UDP: 3496 self.__sock.settimeout(self.__timeout) 3497 self.__sock.connect((host, port)) 3498 self.__connected = True 3499 self.__thread.start()
3500
3501 - def close(self):
3502 """Close the InSim connection. Sends a TINY_CLOSE before releasing the 3503 socket. 3504 3505 """ 3506 self.__close() 3507 self.onInSimEvent(EVT_CLOSE, CLOSE_REQUEST)
3508
3509 - def __close(self):
3510 """Internal close which does not raise an InSimClosed event. 3511 3512 """ 3513 if self.__connected: 3514 self.__connected = False 3515 self.send(ISP_TINY, SubT=TINY_CLOSE) 3516 self.__sock.close()
3517
3518 - def send(self, packetType, **values):
3519 """Send a packet to InSim. 3520 3521 >>> # Example. 3522 >>> InSim.send(ISP_ISI, ReqI=1, Admin='password', IName='example') 3523 3524 @type packetType: enum 3525 @param packetType: Type of packet to send, from the ISP_ enumeration. 3526 @type values: args 3527 @param values: Values to initialise the packet with. 3528 3529 """ 3530 self.sendB(_PACKET_DEFS[packetType](**values).pack())
3531
3532 - def sendB(self, data):
3533 """Send raw binary data to InSim. 3534 3535 @type data: string 3536 @param data: The data to send, as a binary formatted string. 3537 3538 """ 3539 self.__sock.send(data)
3540
3541 - def sendP(self, *packets):
3542 """Send one or more packets to InSim. 3543 3544 @type packets: list 3545 @param packets: A list of packets to send. 3546 3547 """ 3548 [self.sendB(packet.pack()) for packet in packets]
3549
3550 - def __receiveThread(self):
3551 """The internal receive thread. 3552 3553 """ 3554 try: 3555 while self.__connected: 3556 data = self.__sock.recv(_INSIM_BUFFER_SIZE) 3557 if data: 3558 self.__buffer.receive(data) 3559 for packet in self.__buffer.packets(): 3560 self.onPacketReceived(packet) 3561 else: 3562 self.onInSimEvent(EVT_CLOSE, CLOSE_LFS) 3563 break 3564 except socket.timeout, err: 3565 self.onInSimEvent(EVT_TIMEOUT, self.__timeout) 3566 except Exception, err: 3567 self.onInSimEvent(EVT_ERROR, err) 3568 finally: 3569 self.__close()
3570
3571 - def onPacketReceived(self, data):
3572 """Virtual method called when a packet is received. Handles the keep 3573 alive pulse and raises packet events. 3574 3575 @type data: string 3576 @param data: Packet data as a binary formatted string. 3577 3578 """ 3579 packetType = _packetType(data) 3580 3581 self.__keepAlive(packetType, data) 3582 3583 # Raise packet event. 3584 if packetType in self.__callbacks: 3585 for callback, customPacket in self.__callbacks[packetType]: 3586 if customPacket: 3587 packet = customPacket() 3588 else: 3589 packet = _PACKET_DEFS[packetType]() 3590 packet.unpack(data) 3591 callback(self, packet)
3592
3593 - def __keepAlive(self, packetType, data):
3594 if packetType == ISP_TINY: 3595 if _tinyType(data) == TINY_NONE: 3596 self.sendB(data)
3597
3598 - def run(self):
3599 """Block the calling thread until the InSim connection has closed. 3600 3601 """ 3602 self.__thread.join()
3603
3604 - def onInSimEvent(self, evtType, args):
3605 """Virtual method called when an InSim event is raised. 3606 3607 @type evtType: enum 3608 @param evtType: The type of event to raise an event for. 3609 @type args: args 3610 @param args: Event arguments. 3611 3612 """ 3613 if evtType in self.__callbacks: 3614 for callback, _ in self.__callbacks[evtType]: 3615 callback(self, args)
3616
3617 - def bind(self, evtType, callback, customPacket=None):
3618 """Bind a packet callback event-handler. 3619 3620 @type evtType: enum 3621 @param evtType: Type of evt to bind. 3622 @type callback: function 3623 @param callback: Function to call when the event is raised. 3624 @type customPacket: object 3625 @param customPacket: A custom packet object to use when unpacking 3626 packet data. 3627 3628 """ 3629 if not evtType in self.__callbacks: 3630 self.__callbacks[evtType] = [] 3631 self.__callbacks[evtType].append((callback, customPacket))
3632
3633 - def unbind(self, evtType, callback):
3634 """Unbind a packet callback event-handler. 3635 3636 @type evtType: enum 3637 @param evtType: Type of event to unbind. 3638 @type callback: function 3639 @param callback: Event-handler to unbind for this packet type. 3640 3641 """ 3642 for i in range(len(self.__callbacks[evtType])): 3643 if self.__callbacks[evtType][i][0] == callback: 3644 del self.__callbacks[evtType][i] 3645 break
3646
3647 - def isBound(self, evtType, callback):
3648 """Get if a specific event-handler has been bound., 3649 3650 @type evtType: enum 3651 @param evtType: Event type to check for. 3652 @type callback: function 3653 @param callback: Callback to check for. 3654 3655 @rtype: boolean 3656 @return: True if the event-handler has been bound. 3657 3658 """ 3659 if packetType in self.__callbacks: 3660 for callback_, customPacket in self.__callbacks[packetType]: 3661 if callback_ == callback: 3662 return True 3663 return False
3664
3665 - def raisePacketEvent(self, *packets):
3666 """Raise a packet event as if the packet was received through InSim. 3667 Useful for testing and debugging. 3668 3669 @type packets: list 3670 @param packets: A list of packets to raise events for. 3671 3672 """ 3673 for packet in packets: 3674 if packet.Type in self.__callbacks: 3675 for callback, customPacket in self.__callbacks[packet.Type]: 3676 callback(self, packet)
3677 3678
3679 -class OutReceiver:
3680 """Class to handle incoming UDP packets from LFS, OutSim, OutGauge and 3681 IS_MCI/IS_NLP packets. 3682 3683 """
3684 - def __init__(self, mode=OUT_INSIM, timeout=10.0, name='default'):
3685 """Initailise the OutReceiver object. The mode defines what sort of 3686 packets OutReceiver raises events for. 3687 3688 >>> OUT_INSIM - InSim packets, such as MCI and NLP. 3689 >>> OUT_OUTSIM - OutSim packets. 3690 >>> OUT_OUTGAUGE - OutGauge packets. 3691 3692 Upon timing out OutReceiver raises EVT_TIMEOUT event. 3693 3694 @type mode: enum 3695 @param mode: The mode for the OutReceiver from the OUT_ enumeration. 3696 @type timeout: number 3697 @param timeout: The number of seconds to wait before timing out. 3698 @type name: string 3699 @param name: An optional name for the OutReceiver. 3700 3701 """ 3702 self.__mode = mode 3703 self.__timeout = timeout 3704 self.__name = name 3705 self.__sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 3706 self.__sock.settimeout(timeout) 3707 self.__thread = threading.Thread(target=self.__receiveThread) 3708 self.__callbacks = {} 3709 self.__connected = False
3710
3711 - def setTimeout(self, timeout):
3712 """Set the timeout seconds. 3713 3714 @type timeout: number 3715 @param timeout: The timeout. 3716 3717 """ 3718 self.__timeout = timeout
3719
3720 - def getTimeout(self):
3721 """Get the timeout seconds. 3722 3723 @rtype: number 3724 @return: The timeout. 3725 3726 """ 3727 return self.__timeout
3728
3729 - def getName(self):
3730 """Get the name of the socket. 3731 3732 @rtype: string 3733 @return: The socket name. 3734 3735 """ 3736 return self.__name
3737
3738 - def setName(self, name):
3739 """Set the name of the socket. 3740 3741 @type name: string 3742 @param name: The socket name. 3743 3744 """ 3745 self.__name = name
3746
3747 - def isConnected(self):
3748 """Get if the OutReceiver is connected. 3749 3750 @rtype: boolean 3751 @return: True if connected. 3752 3753 """ 3754 return self.__connected
3755
3756 - def start(self, host='localhost', port=30000):
3757 """Start the OutReceiver. 3758 3759 @type host: string 3760 @param host: The host IP to receive data on. 3761 @type port: number 3762 @param port: The port to receive data through. 3763 3764 """ 3765 self.__sock.bind((host, port)) 3766 self.__connected = True 3767 self.__thread.start()
3768
3769 - def stop(self):
3770 """Stop the OutReceiver. 3771 3772 """ 3773 self.__stop() 3774 self.onOutEvent(EVT_CLOSE, CLOSE_REQUEST)
3775
3776 - def __stop(self):
3777 """Internal version of stop() that doesn't raise a close event. 3778 3779 """ 3780 self.__sock.close() 3781 self.__connected = False
3782
3783 - def run(self):
3784 """Block the calling thread until the OutReceiver has closed. 3785 3786 """ 3787 self.__thread.join()
3788
3789 - def bind(self, evtType, callback):
3790 """Bind an event-handler. 3791 3792 @type evtType: enum 3793 @param evtType: Type of event. 3794 @type callback: function 3795 @param callback: Function to bind. 3796 3797 """ 3798 if evtType not in self.__callbacks: 3799 self.__callbacks[evtType] = [] 3800 self.__callbacks[evtType].append(callback)
3801
3802 - def unbind(self, evtType, callback):
3803 """Unbind an event-handler. 3804 3805 @type evtType: enum 3806 @param evtType: Type of event. 3807 @type callback: function 3808 @param callback: Function to unbind. 3809 3810 """ 3811 self.__callbacks[evtType].remove(callback)
3812
3813 - def isBound(self, evtType, callback):
3814 """Get if an event-handler has been bound. 3815 3816 @type evtType: enum 3817 @param evtType: Type of event. 3818 @type callback: function 3819 @param callback: Function to check. 3820 3821 @rtype: boolean 3822 @return: True if the function has been bound. 3823 3824 """ 3825 if evtType in self.__callbacks: 3826 return callback in self.__callbacks[evtType] 3827 return False
3828
3829 - def __receiveThread(self):
3830 """Internal UDP receive thread. 3831 3832 """ 3833 try: 3834 while self.__connected: 3835 data = self.__sock.recv(_INSIM_BUFFER_SIZE) 3836 if data: 3837 if self.__mode == OUT_OUTGAUGE: 3838 packet = OutGaugePack() 3839 type_ = ISP_OUTGAUGE 3840 elif self.__mode == OUT_OUTSIM: 3841 packet = OutSimPack() 3842 type_ = ISP_OUTSIM 3843 else: 3844 type_ = _packetType(data) 3845 packet = _PACKET_DEFS[type_]() 3846 packet.unpack(data) 3847 if type_ in self.__callbacks: 3848 [callback(self, packet) for callback in self.__callbacks[type_]] 3849 else: 3850 self.onOutEvent(EVT_CLOSE, CLOSE_LFS) 3851 break 3852 except socket.timeout, err: 3853 self.onOutEvent(EVT_TIMEOUT, self.__timeout) 3854 except Exception, err: 3855 self.onOutEvent(EVT_ERROR, err) 3856 finally: 3857 self.__stop()
3858
3859 - def onOutEvent(self, evtType, args):
3860 """Virtual method called when a Closed event is raised. 3861 3862 @type evtType: enum 3863 @param evtType: The type of the event from the EVT_ enumeration. 3864 @type args: args 3865 @param args: The close arguments. 3866 3867 """ 3868 if evtType in self.__callbacks: 3869 [callback(self, args) for callback in self.__callbacks[evtType]]
3870
3871 - def raisePacketEvent(self, *packets):
3872 """Raise a packet-event as if it has been received by the OutReceiver. 3873 3874 @type packets: list 3875 @param packets: A list of packets to raise events for. 3876 3877 """ 3878 for packet in packets: 3879 if isinstance(packet, OutGaugePack): 3880 type_ = ISP_OUTGAUGE 3881 elif isinstance(packet, OutSimPack): 3882 type_ = ISP_OUTSIM 3883 else: 3884 type_ = packet.Type 3885 if type_ in self.__callbacks: 3886 [callback(self, packet) for callback in self.__callbacks[type_]]
3887 3888
3889 -class OutSim(OutReceiver):
3890 """Motion Simulator Support. 3891 3892 Simple wrapper for OutReceiver, which handles an OutSim socket. See 3893 OutReceiver for more info. 3894 3895 """
3896 - def __init__(self, timeout=10.0, name='default'):
3897 """Initailise the OutSim object. 3898 3899 @type timeout: number 3900 @param timeout: The number of seconds to wait before timing out. 3901 @type name: string 3902 @param name: An optional name for the OutSim socket. 3903 3904 """ 3905 OutReceiver.__init__(self, OUT_OUTSIM, timeout, name)
3906 3907
3908 -class OutGauge(OutReceiver):
3909 """External dashboard support. 3910 3911 Simple wrapper for OutReceiver, which handles an OutGauge socket. See 3912 OutReceiver for more info. 3913 3914 """
3915 - def __init__(self, timeout=10.0, name='default'):
3916 """Initailise the OutGauge object. 3917 3918 @type timeout: number 3919 @param timeout: The number of seconds to wait before timing out. 3920 @type name: string 3921 @param name: An optional name for the OutGauge socket. 3922 3923 """ 3924 OutReceiver.__init__(self, OUT_OUTGAUGE, timeout, name)
3925 3926 3927 if __name__ == '__main__': 3928 pass 3929