# Packet structs _PACKET_FORMAT = { ISP_ISI : struct.Struct('4B2HBcH16s16s'), ISP_VER : struct.Struct('4B8s6sH'), ISP_TINY : struct.Struct('4B'), ISP_SMALL : struct.Struct('4BI'), ISP_STA : struct.Struct('4BfH10B6s2B'), ISP_SCH : struct.Struct('4Bc3B'), ISP_SFP : struct.Struct('4BH2B'), ISP_SCC : struct.Struct('8B'), ISP_CPP : struct.Struct('4B3i3H2Bf2H'), ISP_ISM : struct.Struct('8B32s'), ISP_MSO : struct.Struct('8B128s'), ISP_III : struct.Struct('8B64s'), ISP_MST : struct.Struct('4B64s'), ISP_MTC : struct.Struct('8B64s'), ISP_MOD : struct.Struct('4B4i'), ISP_VTN : struct.Struct('8B'), ISP_RST : struct.Struct('8B6s2B6H'), ISP_NCN : struct.Struct('4B24s24s4B'), ISP_CNL : struct.Struct('8B'), ISP_CPR : struct.Struct('4B24s8s'), ISP_NPL : struct.Struct('6BH24s8s4s16s8Bi4B'), ISP_PLP : struct.Struct('4B'), ISP_PLL : struct.Struct('4B'), ISP_LAP : struct.Struct('4B2I2H4B'), ISP_SPX : struct.Struct('4B2I4B'), ISP_PIT : struct.Struct('4B2H8B2I'), ISP_PSF : struct.Struct('4B2I'), ISP_PLA : struct.Struct('8B'), ISP_CCH : struct.Struct('8B'), ISP_PEN : struct.Struct('8B'), ISP_TOC : struct.Struct('8B'), ISP_FLG : struct.Struct('8B'), ISP_PFL : struct.Struct('4B2H'), ISP_FIN : struct.Struct('4B2I4B2H'), ISP_RES : struct.Struct('4B24s24s8s4s2I4B2H2BH'), ISP_REO : struct.Struct('36B'), ISP_NLP : struct.Struct('4B'), ISP_MCI : struct.Struct('4B'), ISP_MSX : struct.Struct('4B96s'), ISP_MSL : struct.Struct('4B128s'), ISP_CRS : struct.Struct('4B'), ISP_BFN : struct.Struct('8B'), ISP_AXI : struct.Struct('6BH32s'), ISP_AXO : struct.Struct('4B'), ISP_BTN : struct.Struct('12B'), ISP_BTC : struct.Struct('8B'), ISP_BTT : struct.Struct('8B96s'), ISP_RIP : struct.Struct('8B2I64s'), ISP_SSH : struct.Struct('8B32s'), ISP_NODELAP : struct.Struct('2H2B'), ISP_COMPCAR : struct.Struct('2H4B3i3Hh'), OUTSIM : struct.Struct('I12f4i'), OUTGAUGE : struct.Struct('I4sH2B12f16s16si'), } class IS_ISI: def __init__(self, ReqI = 0, UDPPort = 0, Flags = 0, Prefix = '\0', Interval = 0, Admin = '', IName = 'pyinsim_app'): self.Size = 44 self.Type = ISP_ISI self.ReqI = ReqI self.Zero = 0 self.UDPPort = UDPPort self.Flags = Flags self.Sp0 = 0 self.Prefix = Prefix self.Interval = Interval self.Admin = Admin self.IName = IName def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.Zero, self.UDPPort, self.Flags, self.Sp0, self.Prefix, self.Interval, self.Admin, self.IName) class IS_VER: def __init__(self): self.Size = 20 self.Type = ISP_VER def unpack(self, data): self.ReqI, self.Zero, self.Version, self.Product, self.InSimVer = _PACKET_FORMAT[self.Type].unpack(data)[2:] self.Version = _eatNullChars(self.Version) self.Product = _eatNullChars(self.Product) class IS_TINY: def __init__(self, ReqI = 0, SubT = TINY_NONE): self.Size = 4 self.Type = ISP_TINY self.ReqI = ReqI self.SubT = SubT def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.SubT) def unpack(self, data): self.ReqI, self.SubT = _PACKET_FORMAT[self.Type].unpack(data)[2:] class IS_SMALL: def __init__(self, ReqI = 0, SubT = SMALL_NONE, UVal = 0): self.Size = 8 self.Type = ISP_SMALL self.ReqI = ReqI self.SubT = SubT self.UVal = UVal def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.SubT, self.UVal) def unpack(self, data): self.ReqI, self.SubT, self.UVal = _PACKET_FORMAT[self.Type].unpack(data)[2:] class IS_STA: def __init__(self): self.Size = 28 self.Type = ISP_STA def unpack(self, data): 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 = _PACKET_FORMAT[self.Type].unpack(data)[2:] self.Track = _eatNullChars(self.Track) class IS_SCH: def __init__(self, CharB = '\0', Flags = 0): self.Size = 8 self.Type = ISP_SCH self.ReqI = 0 self.Zero = 0 self.CharB = CharB self.Flags = Flags self.Spare2 = 0 self.Spare3 = 0 def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.Zero, self.CharB, self.Flags, self.Spare2, self.Spare3) class IS_SFP: def __init__(self, Flag = 0, OffOn = 0): self.Size = 8 self.Type = ISP_SFP self.ReqI = 0 self.Zero = 0 self.Flag = Flag self.OffOn = OffOn self.Sp3 = 0 def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.Zero, self.Flag, self.OffOn, self.Sp3) class IS_SCC: def __init__(self, ViewPLID = 255, InGameCam = 255): self.Size = 8 self.Type = ISP_SCC self.ReqI = 0 self.Zero = 0 self.ViewPLID = ViewPLID self.InGameCam = InGameCam self.Sp2 = 0 self.Sp3 = 0 def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.Zero, self.ViewPLID, self.InGameCam, self.Sp2, self.Sp3) class IS_CPP: def __init__(self, Pos = (0,0,0), H = 0, P = 0, R = 0, ViewPLID = 0, InGameCam = 0, FOV = 0.0, Time = 0, Flags = 0): self.Size = 32 self.Type = ISP_CPP self.ReqI = ReqI self.Zero = 0 self.Pos = Pos self.H = H self.P = P self.R = R self.ViewPLID = ViewPLID self.InGameCam = InGameCam self.FOV = FOV self.Time = Time self.Flags = Flags def pack(self): return _PACKET_FORMAT[self.Type].pack(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) def unpack(self, data): 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 = _PACKET_FORMAT[self.Type].unpack(data)[2:] class IS_ISM: def __init__(self): self.Size = 40 self.Type = ISP_ISM def unpack(self, data): self.ReqI, self.Zero, self.Host, self.Sp1, self.Sp2, self.Sp3, self.HName = _PACKET_FORMAT[self.Type].unpack(data)[2:] self.HName = _eatNullChars(self.HName) class IS_MSO: def __init__(self): self.Size = 136 self.Type = ISP_MSO self.ReqI = 0 def unpack(self, data): self.Zero, self.UCID, self.PLID, self.UserType, self.TextStart, self.Msg = _PACKET_FORMAT[self.Type].unpack(data)[3:] self.Msg = _eatNullChars(self.Msg) class IS_III: def __init__(self): self.Size = 72 self.Type = ISP_III self.ReqI = 0 def unpack(self, data): self.Zero, self.UCID, self.PLID, self.Sp2, self.Sp3, self.Msg = _PACKET_FORMAT[self.Type].pack(data)[3:] class IS_MST: def __init__(self, Msg = ''): self.Size = 68 self.Type = ISP_MST self.ReqI = 0 self.Zero = 0 self.Msg = Msg def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.Zero, self.Msg) class IS_MTC: def __init__(self, UCID = 0, PLID = 0, Msg = ''): self.Size = 72 self.Type = ISP_MTC self.ReqI = 0 self.Zero = 0 self.UCID = UCID self.PLID = PLID self.Sp2 = 0 self.Sp3 = 0 self.Msg = Msg def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.Zero, self.UCID, self.PLID, self.Sp2, self.Sp3, self.Msg) class IS_MOD: def __init__(self, Bits16 = 0, RR = 0, Width = 0, Height = 0): self.Size = 20 self.Type = ISP_MOD self.ReqI = 0 self.Zero = 0 self.Bits16 = Bits16 self.RR = RR self.Width = Width self.Height = Height def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.Zero, self.Bits16, self.RR, self.Width, self.Height) class IS_VTN: def __init__(self): self.Size = 8 self.Type = ISP_VTN self.ReqI = 0 def unpack(self, data): self.Zero, self.UCID, self.Action, self.Spare2, self.Spare3 = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_RST: def __init__(self): self.Size = 28 self.Type = ISP_RST def unpack(self, data): 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 = _PACKET_FORMAT[self.Type].unpack(data)[2:] self.Track = _eatNullChars(self.Track) class IS_NCN: def __init__(self): self.Size = 56 self.Type = ISP_NCN def unpack(self, data): self.ReqI, self.UCID, self.UName, self.PName, self.Admin, self.Total, self.Flags, self.Sp3 = _PACKET_FORMAT[self.Type].unpack(data)[2:] self.UName = _eatNullChars(self.UName) self.PName = _eatNullChars(self.PName) class IS_CNL: def __init__(self): self.Size = 8 self.Type = ISP_CNL self.ReqI = 0 def unpack(self, data): self.UCID, self.Reason, self.Total, self.Sp2, self.Sp3 = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_CPR: def __init__(self): self.Size = 36 self.Type = ISP_CPR self.ReqI = 0 def unpack(self, data): self.UCID, self.PName, self.Plate = _PACKET_FORMAT[self.Type].unpack(data)[3:] self.PName = _eatNullChars(self.PName) self.Plate = _eatNullChars(self.Plate) class IS_NPL: def __init__(self): self.Size = 76 self.Type = ISP_NPL def unpack(self, data): self.Tyres = [0,0,0,0] 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 = _PACKET_FORMAT[self.Type].unpack(data)[2:] self.PName = _eatNullChars(self.PName) self.Plate = _eatNullChars(self.Plate) self.CName = _eatNullChars(self.CName) self.SName = _eatNullChars(self.SName) class IS_PLP: def __init__(self): self.Size = 4 self.Type = ISP_PLP self.ReqI = 0 def unpack(self, data): self.PLID = ord(data[3]) class IS_PLL: def __init__(self): self.Size = 4 self.Type = ISP_PLL self.ReqI = 0 def unpack(self, data): self.PLID = ord(data[3]) class IS_LAP: def __init__(self): self.Size = 20 self.Type = ISP_LAP self.ReqI = 0 def unpack(self, data): self.PLID, self.LTime, self.ETime, self.LapsDone, self.Flags, self.Sp0, self.Penalty, self.NumStops, self.Sp3 = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_SPX: def __init__(self): self.Size = 16 self.Type = ISP_SPX self.ReqI = 0 def unpack(self, data): self.PLID, self.STime, self.ETime, self.Split, self.Penalty, self.NumStops, self.Sp3 = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_PIT: def __init__(self): self.Size = 24 self.Type = ISP_PIT self.ReqI = 0 def unpack(self, data): self.Tyres = [0,0,0,0] 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 = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_PSF: def __init__(self): self.Size = 12 self.Type = ISP_PSF self.ReqI = 0 def unpack(self, data): self.PLID, self.STime, self.Spare = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_PLA: def __init__(self): self.Size = 8 self.Type = ISP_PLA self.ReqI = 0 def unpack(self, data): self.PLID, self.Fact, self.Sp1, self.Sp2, self.Sp3 = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_CCH: def __init__(self): self.Size = 8 self.Type = ISP_CCH self.ReqI = 0 def unpack(self, data): self.PLID, self.Camera, self.Sp1, self.Sp2, self.Sp3 = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_PEN: def __init__(self): self.Size = 8 self.Type = ISP_PEN self.ReqI = 0 def unpack(self, data): self.PLID, self.OldPen, self.NewPen, self.Reason, self.Sp3 = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_TOC: def __init__(self): self.Size = 8 self.Type = ISP_TOC self.ReqI = 0 def unpack(self, data): self.PLID, self.OldUCID, self.NewUCID, self.Sp2, self.Sp3 = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_FLG: def __init__(self): self.Size = 8 self.Type = ISP_FLG self.ReqI = 0 def unpack(self, data): self.PLID, self.OffOn, self.Flag, self.CarBehind, self.Sp3 = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_PFL: def __init__(self): self.Size = 8 self.Type = ISP_PFL self.ReqI = 0 def unpack(self, data): self.PLID, self.Flags, self.Spare = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_FIN: def __init__(self): self.Size = 20 self.Type = ISP_FIN self.ReqI = 0 def unpack(self, data): self.PLID, self.TTime, self.BTime, self.SpA, self.NumStops, self.Confirm, self.SpB, self.LapsDone, self.Flags = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_RES: def __init__(self): self.Size = 84 self.Type = ISP_RES def unpack(self, data): 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 = _PACKET_FORMAT[self.Type].unpack(data)[2:] self.UName = _eatNullChars(self.UName) self.PName = _eatNullChars(self.PName) self.Plate = _eatNullChars(self.Plate) self.CName = _eatNullChars(self.CName) class IS_REO: def __init__(self, PLID = []): self.Size = 36 self.Type = ISP_REO self.ReqI = 0 self.NumP = len(PLID) - PLID.count(0) self.PLID = PLID def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.NumP, *self.PLID) def unpack(self, data): data = _PACKET_FORMAT[self.Type].unpack(data)[2:] self.ReqI, self.NumP = data[:2] self.PLID = data[2:] class IS_NLP: def __init__(self): self.Type = ISP_NLP self.NodeLap = [] def unpack(self, data): self.Size, self.Type, self.ReqI, self.NumP = _PACKET_FORMAT[self.Type].unpack(data[:4]) for nlpi in xrange(4, self.NumP * 6 + 4, 6): self.NodeLap.append(NODELAP(*_PACKET_FORMAT[ISP_NODELAP].unpack(data[nlpi:nlpi + 6]))) class IS_MCI: def __init__(self): self.Type = ISP_MCI self.CompCar = [] def unpack(self, data): self.Size, self.Type, self.ReqI, self.NumC = _PACKET_FORMAT[self.Type].unpack(data[:4]) for cci in xrange(4, self.NumC * 28 + 4, 28): self.CompCar.append(COMPCAR(*_PACKET_FORMAT[ISP_COMPCAR].unpack(data[cci:cci + 28]))) class IS_MSX: def __init__(self, Msg = ''): self.Size = 100 self.Type = ISP_MSX self.ReqI = 0 self.Zero = 0 self.Msg = Msg def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.Zero, self.Msg) class IS_MSL: def __init__(self, Sound = 0, Msg = ''): self.Size = 132 self.Type = ISP_MSL self.ReqI = 0 self.Sound = Sound self.Msg = Msg def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.Sound, self.Msg) class IS_CRS: def __init__(self): self.Size = 4 self.Type = ISP_CRS self.ReqI = 0 def unpack(self, data): self.PLID = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_BFN: def __init__(self, SubT = BFN_DEL_BTN, UCID = 255, ClickID = 0, Inst = 0): self.Size = 8 self.Type = ISP_BFN self.ReqI = 0 self.SubT = SubT self.UCID = UCID self.ClickID = ClickID self.Inst = Inst self.Sp3 = 0 def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.SubT, self.UCID, self.ClickID, self.Inst, self.Sp3) def unpack(self, data): self.SubT, self.UCID, self.ClickID, self.Inst, self.Sp3 = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_AXI: def __init__(self): self.Size = 40 self.Type = ISP_AXI def unpack(self, data): self.ReqI, self.Zero, self.AXStart, self.NumCP, self.NumO, self.LName = _PACKET_FORMAT[self.Type].unpack(data)[2:] self.LName = eatNullChars(self.LName) class IS_AXO: def __init__(self): self.Size = 4 self.Type = ISP_AXO self.ReqI = 0 def unpack(self, data): self.PLID = _PACKET_FORMAT[self.Type].unpack(data)[3:] class IS_BTN: def __init__(self, ReqI = 1, UCID = 0, ClickID = 0, Inst = 0, BStyle = 0, TypeIn = 0, L = 0, T = 0, W = 0, H = 0, Text = ''): self.Size = 12 # + TEXT_SIZE (a multiple of 4) self.Type = ISP_BTN self.ReqI = ReqI self.UCID = UCID self.ClickID = ClickID self.Inst = Inst self.BStyle = BStyle self.TypeIn = TypeIn self.L = L self.T = T self.W = W self.H = H self.Text = Text def pack(self): TEXT_SIZE = int(math.ceil(len(self.Text) / 4.0)) * 4 return _PACKET_FORMAT[self.Type].pack(self.Size + TEXT_SIZE, self.Type, self.ReqI, self.UCID, self.ClickID, self.Inst, self.BStyle, self.TypeIn, self.L, self.T, self.W, self.H) + struct.pack(str(TEXT_SIZE) + 's', self.Text) class IS_BTC: def __init__(self): self.Size = 8 self.Type = ISP_BTC def unpack(self, data): self.ReqI, self.UCID, self.ClickID, self.Inst, self.CFlags, self.Sp3 = _PACKET_FORMAT[self.Type].unpack(data)[2:] class IS_BTT: def __init__(self): self.Size = 104 self.Type = ISP_BTT def unpack(self, data): self.ReqI, self.UCID, self.ClickID, self.Inst, self.TypeIn, self.Sp3, self.Text = _PACKET_FORMAT[self.Type].unpack(data)[2:] self.Text = _eatNullChars(self.Text) class IS_RIP: def __init__(self, ReqI = 1, Paused = 0, Options = 0, CTime = 0, RName = 0): self.Size = 80 self.Type = ISP_RIP self.ReqI = ReqI self.Error = 0 self.MPR = 0 self.Paused = Paused self.Options = Options self.Sp3 = 0 self.CTime = CTime self.TTime = 0 self.RName = RName def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.Error, self.MPR, self.Paused, self.Options, self.Sp3, self.CTime, self.TTime, self.RName) def unpack(self, data): self.ReqI, self.Error, self.MPR, self.Paused, self.Options, self.Sp3, self.CTime, self.TTime, self.RName = _PACKET_FORMAT[self.Type].unpack(data)[2:] self.RName = _eatNullChars(self.RName) class IS_SSH: def __init__(self, ReqI = 1, BMP = ''): self.Size = 40 self.Type = ISP_SSH self.ReqI = ReqI self.Error = 0 self.Sp0 = 0 self.Sp1 = 0 self.Sp2 = 0 self.Sp3 = 0 self.BMP = BMP def pack(self): return _PACKET_FORMAT[self.Type].pack(self.Size, self.Type, self.ReqI, self.Error, self.Sp0, self.Sp1, self.Sp2, self.Sp3, self.BMP) def unpack(self, data): self.ReqI, self.Error, self.Sp0, self.Sp1, self.Sp2, self.Sp3, self.BMP = _PACKET_FORMAT[self.Type].unpack(data)[2:] class NODELAP: def __init__(self, Node, Lap, PLID, Position): self.Node = Node self.Lap = Lap self.PLID = PLID self.Position = Position class COMPCAR: