private static void HandleMessage(NetMessageType type, NetConnection source, NetBuffer buffer) { switch (type) { case NetMessageType.DebugMessage: WriteToConsole(buffer.ReadString()); break; case NetMessageType.StatusChanged: WriteToConsole("New status: " + source.Status + " (" + buffer.ReadString() + ")"); UpdateStatisticsDisplay(source); break; case NetMessageType.Data: //System.IO.File.AppendAllText("C:\\receivedpackets.txt", s_userMessagesReceived.ToString() + ": " + msg.ReadString() + " (" + msg.m_sequenceNumber + ")" + Environment.NewLine); s_userMessagesReceived++; // simulate some processing of the message here for (int i = 0; i < buffer.LengthBytes - 2; i++) buffer.ReadByte(); // check checksum ushort checksum = NetChecksum.Adler16(buffer.Data, 0, buffer.LengthBytes - 2); ushort given = buffer.ReadUInt16(); if (checksum != given) WriteToConsole("Wrong checksum! Expected " + checksum + " found given " + given); double b = s_userMessagesReceived; for (int i = 0; i < 1000; i++) b += Math.Sqrt((double)i) / Math.Sin(s_tmp); s_tmp += b / 10000.0; break; default: break; } }
public static void StatusChangeHandler(NetClient client, NetBuffer buffer) { string status_msg = buffer.ReadString(); NetConnectionStatus status = (NetConnectionStatus)buffer.ReadByte(); if (status == NetConnectionStatus.Connected) { Console.WriteLine("Client: Connected"); Console.Write("Client: Starting IOS"); int i; for (i = 0; i < 10; i++) { Console.Write("."); Thread.Sleep(500); } Console.WriteLine(""); //Show the IOS Master form System.Windows.Forms.Application.EnableVisualStyles(); System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); System.Windows.Forms.Application.Run(new MasterForm()); } if (status == NetConnectionStatus.Disconnected) { Console.WriteLine("Client: Disconnected - " + status_msg); } }
internal string ReadStringTable(NetBuffer buffer) { byte b = buffer.ReadByte(); bool stringFollows = ((b & 1) == 0); bool shortVal = ((b & 2) == 0); int val = 0; if (shortVal) val = b >> 2; else val = ((b & (255 << 2)) << 6) | buffer.ReadByte(); string retval = string.Empty; if (stringFollows) { retval = buffer.ReadString(); m_stringTable[retval] = val; m_stringTableLookUp[val] = retval; // // Send confirmation // NetBuffer buf = new NetBuffer(2); buf.Write((ushort)val); m_owner.QueueSingleUnreliableSystemMessage( NetSystemType.StringTableAck, buf, m_remoteEndPoint, false ); return retval; } if (!m_stringTableLookUp.TryGetValue(val, out retval)) { // Ack! Failed to find string table value! throw new Exception("ACK!"); } return retval; }
public void Read(NetBuffer im) { PluginName = im.ReadString(); MethodName = im.ReadString(); RspType = im.ReadByte(); if (RspType == StringDataType) { StringCommandRsp = im.ReadString(); } else if (RspType == BinaryDataType) { int l = im.ReadInt32(); BinaryCommandRsp = im.ReadBytes(l); } }
public static void StatusChangeHandler(NetClient client, NetBuffer buffer) { string status_msg = buffer.ReadString(); NetConnectionStatus status = (NetConnectionStatus)buffer.ReadByte(); if (status == NetConnectionStatus.Connected) { Console.WriteLine("Plugin: Connected"); } if (status == NetConnectionStatus.Disconnected) { Console.WriteLine("Plugin: Disconnected"); } }
/// <summary> /// Read this message from the packet buffer /// </summary> /// <returns>new read pointer position</returns> internal void ReadFrom(NetBuffer buffer, IPEndPoint endpoint) { m_senderEndPoint = endpoint; // read header byte header = buffer.ReadByte(); m_type = (NetMessageLibraryType)(header & 7); m_sequenceChannel = (NetChannel)(header >> 3); m_sequenceNumber = buffer.ReadUInt16(); int payLen = (int)buffer.ReadVariableUInt32(); // copy payload into message buffer m_data.EnsureBufferSize(payLen * 8); buffer.ReadBytes(m_data.Data, 0, payLen); m_data.Reset(0, payLen * 8); return; }
void ParseGameState(NetBuffer msg) { clc.connectPacketCount = 0; // wipe local client state ClearState(); // a gamestate always marks a server command sequence clc.serverCommandSequence = msg.ReadInt32(); // parse all the configstrings and baselines while (true) { int cmd = msg.ReadByte(); if (cmd == (int)svc_ops_e.svc_EOF) break; if (cmd == (int)svc_ops_e.svc_configstring) { int index = msg.ReadInt16(); string s = msg.ReadString(); cl.gamestate.data.Add(index, s); } else if (cmd == (int)svc_ops_e.svc_baseline) { int newnum = msg.ReadInt32(); if (newnum < 0 || newnum >= 1024) { Common.Instance.Error("ParseGameState: Baseline number out of range: " + newnum); } Common.entityState_t nullstate = new Common.entityState_t(); Net.Instance.MSG_ReadDeltaEntity(msg, ref nullstate, ref cl.entityBaselines[newnum], newnum); } else { Common.Instance.Error("ParseGameState: bad command byte"); } } clc.clientNum = msg.ReadInt32(); // parse useful values out of CS_SERVERINFO //ParseServerInfo(); // parse serverId and other cvars SystemInfoChanged(); InitDownloads(); }
/* ================ CL_ParseSnapshot If the snapshot is parsed properly, it will be copied to cl.snap and saved in cl.snapshots[]. If the snapshot is invalid for any reason, no changes to the state will be made at all. ================ */ void ParseSnapshot(NetBuffer msg) { // read in the new snapshot to a temporary buffer // we will only copy to cl.snap if it is valid clSnapshot_t newsnap = new clSnapshot_t(); clSnapshot_t old; // we will have read any new server commands in this // message before we got to svc_snapshot newsnap.ServerCommandNum = clc.serverCommandSequence; newsnap.serverTime = msg.ReadInt32(); newsnap.messageNum = clc.serverMessageSequence; int deltaNum = msg.ReadByte(); if (deltaNum <= 0) { newsnap.deltaNum = -1; } else newsnap.deltaNum = newsnap.messageNum - deltaNum; newsnap.snapFlags = msg.ReadByte(); // If the frame is delta compressed from data that we // no longer have available, we must suck up the rest of // the frame, but not use it, then ask for a non-compressed // message if (newsnap.deltaNum <= 0) { newsnap.valid = true; // uncompressed frame old = null; } else { old = cl.snapshots[newsnap.deltaNum & 31]; if (!old.valid) { // should never happen Common.Instance.WriteLine("ParseSnapshot: Delta from invalid frame (not supposed to happen!)."); } else if (old.messageNum != newsnap.deltaNum) { // The frame that the server did the delta from // is too old, so we can't reconstruct it properly. Common.Instance.WriteLine("ParseSnapshot: Delta frame too old."); } else if (cl.parseEntitiesNum - old.parseEntitiesNum > 2048 - 128) { Common.Instance.WriteLine("ParseSnapshot: Delta parseEntitiesNum too old"); } else newsnap.valid = true; // valid delta parse } // read areamask int len = msg.ReadByte(); newsnap.areamask = msg.ReadBytes(32); // read playerinfo if (old != null) { Net.ReadDeltaPlayerstate(msg, old.ps, newsnap.ps); } else Net.ReadDeltaPlayerstate(msg, null, newsnap.ps); // read packet entities ParsePacketEntities(msg, old, newsnap); // if not valid, dump the entire thing now that it has // been properly read if (!newsnap.valid) return; // clear the valid flags of any snapshots between the last // received and this one, so if there was a dropped packet // it won't look like something valid to delta from next // time we wrap around in the buffer int oldMessageNum = cl.snap.messageNum + 1; if (newsnap.messageNum - oldMessageNum >= 32) { oldMessageNum = newsnap.messageNum - 31; } for (; oldMessageNum < newsnap.messageNum; oldMessageNum++ ) { cl.snapshots[oldMessageNum & 31].valid = false; } // copy to the current good spot cl.snap = newsnap; cl.snap.ping = 999; // calculate ping time for (int i = 0; i < 32; i++) { int packetNum = (clc.netchan.outgoingSequence - 1 - i) & 31; if (cl.snap.ps.commandTime >= cl.outPackets[packetNum].p_serverTime) { cl.snap.ping = realtime - cl.outPackets[packetNum].p_realtime; break; } } // save the frame off in the backup array for later delta comparisons cl.snapshots[cl.snap.messageNum & 31] = cl.snap; //Common.Instance.WriteLine(" Snapshot:{0} delta:{1} ping:{2}", cl.snap.messageNum, cl.snap.deltaNum, cl.snap.ping); cl.newSnapshots = true; }
/* ================== SV_UserMove The message usually contains all the movement commands that were in the last three packets, so that the information in dropped packets can be recovered. On very fast clients, there may be multiple usercmd packed into each of the backup packets. ================== */ void UserMove(client_t cl, NetBuffer buf, bool deltaCompressed) { if (deltaCompressed) cl.deltaMessage = cl.messageAcknowledge; else cl.deltaMessage = -1; int cmdCount = buf.ReadByte(); if (cmdCount < 1) { Common.Instance.WriteLine("cmdCount < 1"); return; } if (cmdCount > 32) { Common.Instance.WriteLine("cmdCount > 32"); return; } List<Input.UserCommand> cmds = new List<Input.UserCommand>(); Input.UserCommand oldcmd = new Input.UserCommand(); for (int i = 0; i < cmdCount; i++) { Input.UserCommand cmd = Input.Instance.MSG_ReadDeltaUsercmdKey(buf, ref oldcmd); cmds.Add(cmd); oldcmd = cmd; } // save time for ping calculation cl.frames[cl.messageAcknowledge & 31].messageAcked = (int)time; // if this is the first usercmd we have received // this gamestate, put the client into the world if (cl.state == clientState_t.CS_PRIMED) { ClientEnterWorld(cl, cmds[cmds.Count-1]); // the moves can be processed normaly } if (cl.state != clientState_t.CS_ACTIVE) { cl.deltaMessage = -1; return; } // usually, the first couple commands will be duplicates // of ones we have previously received, but the servertimes // in the commands will cause them to be immediately discarded for (int i = 0; i < cmdCount; i++) { // if this is a cmd from before a map_restart ignore it if (cmds[i].serverTime > cmds[cmdCount - 1].serverTime) { continue; } // don't execute if this is an old cmd which is already executed // these old cmds are included when cl_packetdup > 0 if (cmds[i].serverTime <= cl.lastUsercmd.serverTime) { continue; } ClientThink(cl, cmds[i]); } }
public CommandImplementation(GameState game, NetBuffer buffer) { this.game = game; var time = new Instant(buffer.ReadDouble()); this.game.SetTime(time); int count = buffer.ReadByte(); this.parameters = new List<SingleParameters>(count); for (int i = 0; i < count; i++) { this.parameters.Add(buffer.Read<SingleParameters>()); } }
public PlayerData(NetBuffer msg) : this() { ID = msg.ReadUInt64(); Position = new Vec2(msg.ReadFloat(), msg.ReadFloat()); Type = (ChampionTypes)msg.ReadByte(); Team = msg.ReadBoolean() ? Teams.Left : Teams.Right; MaxHealth = msg.ReadFloat(); Health = msg.ReadFloat(); }
protected void ReadFieldState(NetBuffer buffer) { // bricks & powerups FieldCellSlot[] slots = game.Field.GetCells().slots; for (int i = 0; i < slots.Length; ++i) { BrickCell brick = slots[i].GetBrick(); if (brick != null) { bool hasPowerup = buffer.ReadBoolean(); if (hasPowerup) { brick.powerup = buffer.ReadByte(); } } } // players int senderIndex = buffer.ReadByte(); int playersCount = buffer.ReadByte(); for (int i = 0; i < playersCount; ++i) { Player player = new Player(i); int cx = buffer.ReadByte(); int cy = buffer.ReadByte(); player.SetCell(cx, cy); if (i != senderIndex) { player.SetPlayerInput(new PlayerNetworkInput()); } game.AddPlayer(player); } }
public ParameterGroup(NetBuffer buffer) { this.id = buffer.Read<Id>().Generic<Player>(); int count = buffer.ReadByte(); this.values = new List<ValueParameters>(count); for (int i = 0; i < count; i++) { this.values.Add(buffer.Read<ValueParameters>()); } }
public CommandImplementation(GameState game, NetBuffer buffer) { this.game = game; var time = new Instant(buffer.ReadDouble()); int count = buffer.ReadByte(); this.parameters = new List<ParameterGroup>(count); for (int i = 0; i < count; i++) { this.parameters.Add(new ParameterGroup(buffer)); } }
private static void HandleMessage(NetMessageType type, NetBuffer data) { switch (type) { case NetMessageType.DebugMessage: WriteToConsole(data.ReadString()); break; case NetMessageType.StatusChanged: string statusMessage = data.ReadString(); NetConnectionStatus newStatus = (NetConnectionStatus)data.ReadByte(); WriteToConsole("New status: " + newStatus + " (" + statusMessage + ")"); UpdateStatisticsDisplay(s_client.ServerConnection); break; case NetMessageType.Data: WriteToConsole("Message received: " + data); break; default: WriteToConsole("Unhandled: " + type); break; } }
public void Read(NetBuffer im) { ConnectionType = im.ReadByte(); }
protected void ReadReadyFlags(NetBuffer buffer) { List<Player> players = game.GetPlayers().list; int playersCount = buffer.ReadByte(); Debug.Assert(players.Count == playersCount); for (int i = 0; i < playersCount; ++i) { Player player = players[i]; bool isReady = buffer.ReadBoolean(); if (player.IsNetworkPlayer) { player.IsReady = isReady; } } }
void OnDataReceived(NetBuffer msg) { byte code = msg.ReadByte(); ServerCommand command = (ServerCommand)code; CommandsToDo.AddLast(Utilities.MakePair<ServerCommand, NetBuffer>(command, msg)); ExecuteCommands(); }
protected void ReadRoundResults(NetBuffer buffer) { Debug.Assert(game != null); game.roundIndex = buffer.ReadByte(); game.roundsCount = buffer.ReadByte(); List<Player> players = game.GetPlayersList(); for (int i = 0; i < players.Count; ++i) { Player p = players[i]; p.winsCount = buffer.ReadByte(); p.suicidesCount = buffer.ReadByte(); } }
public StateUpdateEventArgs(NetBuffer msg) : base(msg) { EntitiesUpdatedState = new List<StateUpdateData>(); RemarkableEvents = new List<RemarkableEventData>(); LastAcknowledgedActionID = msg.ReadUInt64(); Time = msg.ReadDouble(); Vec2 velocity = new Vec2(msg.ReadFloat(), msg.ReadFloat()); byte nbClients = msg.ReadByte(); for (byte i = 0; i < nbClients; ++i) { ulong id = msg.ReadUInt64(); Vec2 pos = new Vec2(msg.ReadFloat(), msg.ReadFloat()); ChampionAnimation anim = (ChampionAnimation)msg.ReadByte(); bool facingLeft = msg.ReadBoolean(); EntitiesUpdatedState.Add(new StateUpdateData(id, pos, velocity, anim, facingLeft)); } while (msg.Position != msg.LengthBits) { ServerCommand cmd = (ServerCommand)msg.ReadByte(); RemarkableEventData data = null; switch (cmd) { case ServerCommand.SpellCast: data = new SpellCastEventData( msg.ReadUInt64(), msg.ReadUInt64(), (SpellTypes)msg.ReadByte(), msg.ReadFloat(), new Vec2(msg.ReadFloat(), msg.ReadFloat()), new Vec2(msg.ReadFloat(), msg.ReadFloat()), TimeSpan.FromSeconds(msg.ReadFloat()), msg.ReadFloat(), msg.ReadFloat()); break; case ServerCommand.SpellDisappear: data = new SpellDisappearEventData(msg.ReadUInt64()); break; case ServerCommand.StatsChanged: data = new StatsChangedEventData(msg.ReadUInt64(), msg.ReadFloat()); break; case ServerCommand.ChampionDied: data = new ChampionDiedEventData(msg.ReadUInt64(), msg.ReadUInt64(), msg.ReadUInt32(), msg.ReadUInt32(), msg.ReadUInt32(), msg.ReadUInt32(), TimeSpan.FromSeconds(msg.ReadUInt16())); break; case ServerCommand.StructureStatsChanged: data = new StructureStatsChangedEventData(msg.ReadBoolean() ? Teams.Left : Teams.Right, (StructureTypes)msg.ReadByte(), msg.ReadFloat()); break; case ServerCommand.StructureDestroyed: data = new StructureDestroyedEventData(msg.ReadBoolean() ? Teams.Left : Teams.Right, (StructureTypes)msg.ReadByte()); break; case ServerCommand.EndOfGame: data = new EndOfGameEventData(msg.ReadBoolean() ? Teams.Left : Teams.Right); break; case ServerCommand.TowerPreparingToShoot: data = new TowerPreparingToShootEventData(msg.ReadBoolean() ? Teams.Left : Teams.Right, (StructureTypes)msg.ReadByte()); break; default: Debug.Fail("Unknown server command when updating (unknown remarkable event)"); break; } if (data != null) { RemarkableEvents.Add(data); } } }
protected void SkipReadyFlags(NetBuffer buffer) { int playersCount = buffer.ReadByte(); buffer.ReadInt64(playersCount); }
/// <summary> /// Handle incoming message /// </summary> private void HandleMessage(NetMessageType type, NetBuffer buffer) { switch (type) { case NetMessageType.DebugMessage: // // it's a library debug message; just display it in the console if debugger is attached // Console.WriteLine(buffer.ReadString()); break; case NetMessageType.StatusChanged: // // it's a status change message; set the reason as window title and refresh picture // this.Text = buffer.ReadString(); pictureBox1.Refresh(); break; case NetMessageType.ServerDiscovered: // // it's a server discovered message; connect to the discovered server // m_imageWidth = 0; m_imageHeight = 0; m_lineDisplayed = 0; m_client.Connect(buffer.ReadIPEndPoint()); break; case NetMessageType.Data: // // it's a data message (data sent from the server) // if (m_imageWidth == 0) { // first message is size m_imageWidth = (int)buffer.ReadVariableUInt32(); m_imageHeight = (int)buffer.ReadVariableUInt32(); this.Size = new System.Drawing.Size(m_imageWidth + 40, m_imageHeight + 60); pictureBox1.Image = new Bitmap(m_imageWidth, m_imageHeight); pictureBox1.SetBounds(12, 12, m_imageWidth, m_imageHeight); return; } uint pixelPos = buffer.ReadUInt32(); // it's color data int y = (int)(pixelPos / m_imageWidth); int x = (int)(pixelPos - (y * m_imageWidth)); Bitmap bm = pictureBox1.Image as Bitmap; pictureBox1.SuspendLayout(); int pixels = (buffer.LengthBytes - 4) / 3; for (int i = 0; i < pixels; i++) { // set pixel byte r = buffer.ReadByte(); byte g = buffer.ReadByte(); byte b = buffer.ReadByte(); Color col = Color.FromArgb(r, g, b); if (y > m_imageHeight) continue; bm.SetPixel(x, y, col); x++; if (x >= m_imageWidth) { x = 0; y++; } } pictureBox1.ResumeLayout(); // refresh image every horizontal line if (pixelPos / m_imageWidth > m_lineDisplayed) { m_lineDisplayed = (int)(pixelPos / m_imageWidth); pictureBox1.Refresh(); } break; default: // unhandled break; } }
private void ReadFieldState(NetBuffer msg, Field field) { int bitsForPlayerIndex = NetUtility.BitsToHoldUInt((uint)(field.GetPlayers().GetCount() - 1)); FieldCellSlot[] slots = field.GetCells().slots; for (int i = 0; i < slots.Length; ++i) { FieldCellSlot slot = slots[i]; bool hasStaticCell = msg.ReadBoolean(); if (hasStaticCell) { byte type = msg.ReadByte(BITS_FOR_STATIC_CELL); switch (type) { case CELL_BRICK: { Debug.Assert(slot.ContainsBrick()); break; } case CELL_POWERUP: { int powerup = msg.ReadInt32(BITS_FOR_POWERUP); if (slot.staticCell == null) { field.AddCell(new PowerupCell(powerup, slot.cx, slot.cy)); } else if (!slot.staticCell.IsPowerup()) { field.RemoveCell(slot.staticCell); field.AddCell(new PowerupCell(powerup, slot.cx, slot.cy)); } break; } case CELL_FLAME: { int playerIndex = msg.ReadInt32(bitsForPlayerIndex); if (slot.staticCell == null) { Player player = field.GetPlayers().Get(playerIndex); field.AddCell(new FlameCell(player, slot.cx, slot.cy)); } else if (!slot.staticCell.IsFlame()) { Player player = field.GetPlayers().Get(playerIndex); field.RemoveCell(slot.staticCell); field.AddCell(new FlameCell(player, slot.cx, slot.cy)); } break; } } } else if (slot.staticCell != null && !slot.staticCell.IsSolid()) { field.RemoveCell(slot.staticCell); } } }
static unsafe void Main(string[] args) { // JIT stuff NetBuffer msg = new NetBuffer(20); msg.Write((short)short.MaxValue); // Go double timeStart = NetTime.Now; msg = new NetBuffer(20); for (int n = 0; n < 10000; n++) { msg.Reset(); msg.Write((short)short.MaxValue); msg.Write((short)short.MinValue); msg.Write((short)-42); msg.Write(421); msg.Write((byte)7); msg.Write(-42.8f); if (msg.LengthBytes != 15) throw new Exception("Bad message length"); msg.Write("duke of earl"); int bytesWritten; bytesWritten = msg.WriteVariableInt32(-1); bytesWritten = msg.WriteVariableInt32(5); bytesWritten = msg.WriteVariableInt32(-18); bytesWritten = msg.WriteVariableInt32(42); bytesWritten = msg.WriteVariableInt32(-420); msg.Write((uint)9991); // byte boundary kept until here msg.Write(true); msg.Write((uint)3, 5); msg.Write(8.111f); msg.Write("again"); byte[] arr = new byte[] { 1, 6, 12, 24 }; msg.Write(arr); msg.Write((byte)7, 7); msg.Write(Int32.MinValue); msg.Write(UInt32.MaxValue); msg.WriteRangedSingle(21.0f, -10, 50, 12); // test reduced bit signed writing msg.Write(15, 5); msg.Write(2, 5); msg.Write(0, 5); msg.Write(-1, 5); msg.Write(-2, 5); msg.Write(-15, 5); msg.Write(UInt64.MaxValue); msg.Write(Int64.MaxValue); msg.Write(Int64.MinValue); msg.Write(42); msg.WritePadBits(); int numBits = msg.WriteRangedInteger(0, 10, 5); if (numBits != 4) throw new Exception("Ack WriteRangedInteger failed"); // verify msg.Position = 0; short a = msg.ReadInt16(); short b = msg.ReadInt16(); short c = msg.ReadInt16(); if (a != short.MaxValue || b != short.MinValue || c != -42) throw new Exception("Ack thpth short failed"); if (msg.ReadInt32() != 421) throw new Exception("Ack thphth 1"); if (msg.ReadByte() != (byte)7) throw new Exception("Ack thphth 2"); if (msg.ReadSingle() != -42.8f) throw new Exception("Ack thphth 3"); if (msg.ReadString() != "duke of earl") throw new Exception("Ack thphth 4"); if (msg.ReadVariableInt32() != -1) throw new Exception("ReadVariableInt32 failed 1"); if (msg.ReadVariableInt32() != 5) throw new Exception("ReadVariableInt32 failed 2"); if (msg.ReadVariableInt32() != -18) throw new Exception("ReadVariableInt32 failed 3"); if (msg.ReadVariableInt32() != 42) throw new Exception("ReadVariableInt32 failed 4"); if (msg.ReadVariableInt32() != -420) throw new Exception("ReadVariableInt32 failed 5"); if (msg.ReadUInt32() != 9991) throw new Exception("Ack thphth 4.5"); if (msg.ReadBoolean() != true) throw new Exception("Ack thphth 5"); if (msg.ReadUInt32(5) != (uint)3) throw new Exception("Ack thphth 6"); if (msg.ReadSingle() != 8.111f) throw new Exception("Ack thphth 7"); if (msg.ReadString() != "again") throw new Exception("Ack thphth 8"); byte[] rrr = msg.ReadBytes(4); if (rrr[0] != arr[0] || rrr[1] != arr[1] || rrr[2] != arr[2] || rrr[3] != arr[3]) throw new Exception("Ack thphth 9"); if (msg.ReadByte(7) != 7) throw new Exception("Ack thphth 10"); if (msg.ReadInt32() != Int32.MinValue) throw new Exception("Ack thphth 11"); if (msg.ReadUInt32() != UInt32.MaxValue) throw new Exception("Ack thphth 12"); float v = msg.ReadRangedSingle(-10, 50, 12); // v should be close to, but not necessarily exactly, 21.0f if ((float)Math.Abs(21.0f - v) > 0.1f) throw new Exception("Ack thphth *RangedSingle() failed"); if (msg.ReadInt32(5) != 15) throw new Exception("Ack thphth ReadInt32 1"); if (msg.ReadInt32(5) != 2) throw new Exception("Ack thphth ReadInt32 2"); if (msg.ReadInt32(5) != 0) throw new Exception("Ack thphth ReadInt32 3"); if (msg.ReadInt32(5) != -1) throw new Exception("Ack thphth ReadInt32 4"); if (msg.ReadInt32(5) != -2) throw new Exception("Ack thphth ReadInt32 5"); if (msg.ReadInt32(5) != -15) throw new Exception("Ack thphth ReadInt32 6"); UInt64 longVal = msg.ReadUInt64(); if (longVal != UInt64.MaxValue) throw new Exception("Ack thphth UInt64"); if (msg.ReadInt64() != Int64.MaxValue) throw new Exception("Ack thphth Int64"); if (msg.ReadInt64() != Int64.MinValue) throw new Exception("Ack thphth Int64"); if (msg.ReadInt32() != 42) throw new Exception("Ack thphth end"); msg.SkipPadBits(); if (msg.ReadRangedInteger(0, 10) != 5) throw new Exception("Ack thphth ranged integer"); } // test writevariableuint64 NetBuffer largeBuffer = new NetBuffer(100 * 8); UInt64[] largeNumbers = new ulong[100]; for (int i = 0; i < 100; i++) { largeNumbers[i] = ((ulong)NetRandom.Instance.NextUInt() << 32) | (ulong)NetRandom.Instance.NextUInt(); largeBuffer.WriteVariableUInt64(largeNumbers[i]); } largeBuffer.Position = 0; for (int i = 0; i < 100; i++) { UInt64 ln = largeBuffer.ReadVariableUInt64(); if (ln != largeNumbers[i]) throw new Exception("large fail"); } // // Extended tests on padbits // for (int i = 1; i < 31; i++) { NetBuffer buf = new NetBuffer(); buf.Write((int)1, i); if (buf.LengthBits != i) throw new Exception("Bad length!"); buf.WritePadBits(); int wholeBytes = buf.LengthBits / 8; if (wholeBytes * 8 != buf.LengthBits) throw new Exception("WritePadBits failed! Length is " + buf.LengthBits); } NetBuffer small = new NetBuffer(100); byte[] rnd = new byte[24]; int[] bits = new int[24]; for (int i = 0; i < 24; i++) { rnd[i] = (byte)NetRandom.Instance.Next(0, 65); bits[i] = NetUtility.BitsToHoldUInt((uint)rnd[i]); small.Write(rnd[i], bits[i]); } small.Position = 0; for (int i = 0; i < 24; i++) { byte got = small.ReadByte(bits[i]); if (got != rnd[i]) throw new Exception("Failed small allocation test"); } double timeEnd = NetTime.Now; double timeSpan = timeEnd - timeStart; Console.WriteLine("Trivial tests passed in " + (timeSpan * 1000.0) + " milliseconds"); Console.WriteLine("Creating client and server for live testing..."); NetConfiguration config = new NetConfiguration("unittest"); config.Port = 14242; NetServer server = new NetServer(config); NetBuffer serverBuffer = new NetBuffer(); server.Start(); config = new NetConfiguration("unittest"); NetClient client = new NetClient(config); client.SetMessageTypeEnabled(NetMessageType.Receipt, true); NetBuffer clientBuffer = client.CreateBuffer(); client.Start(); client.Connect("127.0.0.1", 14242); List<string> events = new List<string>(); double end = double.MaxValue; double disconnect = double.MaxValue; while (NetTime.Now < end) { double now = NetTime.Now; NetMessageType nmt; NetConnection sender; // // client // if (client.ReadMessage(clientBuffer, out nmt)) { switch (nmt) { case NetMessageType.StatusChanged: Console.WriteLine("Client: " + client.Status + " (" + clientBuffer.ReadString() + ")"); events.Add("CStatus " + client.Status); if (client.Status == NetConnectionStatus.Connected) { // send reliable message NetBuffer buf = client.CreateBuffer(); buf.Write(true); buf.Write((int)52, 7); buf.Write("Hallon"); client.SendMessage(buf, NetChannel.ReliableInOrder1, new NetBuffer("kokos")); } if (client.Status == NetConnectionStatus.Disconnected) end = NetTime.Now + 1.0; // end in one second break; case NetMessageType.Receipt: events.Add("CReceipt " + clientBuffer.ReadString()); break; case NetMessageType.ConnectionRejected: case NetMessageType.BadMessageReceived: throw new Exception("Failed: " + nmt); case NetMessageType.DebugMessage: // silently ignore break; default: // ignore Console.WriteLine("Ignored: " + nmt); break; } } // // server // if (server.ReadMessage(serverBuffer, out nmt, out sender)) { switch (nmt) { case NetMessageType.StatusChanged: events.Add("SStatus " + sender.Status); Console.WriteLine("Server: " + sender.Status + " (" + serverBuffer.ReadString() + ")"); break; case NetMessageType.ConnectionRejected: case NetMessageType.BadMessageReceived: throw new Exception("Failed: " + nmt); case NetMessageType.Data: events.Add("DataRec " + serverBuffer.LengthBits); bool shouldBeTrue = serverBuffer.ReadBoolean(); int shouldBeFifthTwo = serverBuffer.ReadInt32(7); string shouldBeHallon = serverBuffer.ReadString(); if (shouldBeTrue != true || shouldBeFifthTwo != 52 || shouldBeHallon != "Hallon") throw new Exception("Bad data transmission"); disconnect = now + 1.0; break; case NetMessageType.DebugMessage: // silently ignore break; default: // ignore Console.WriteLine("Ignored: " + nmt); break; } } if (now > disconnect) { server.Connections[0].Disconnect("Bye", 0.1f); disconnect = double.MaxValue; } } // verify events string[] expected = new string[] { "CStatus Connecting", "SStatus Connecting", "CStatus Connected", "SStatus Connected", "DataRec 64", "CReceipt kokos", "SStatus Disconnecting", "CStatus Disconnecting", "SStatus Disconnected", "CStatus Disconnected" }; if (events.Count != expected.Length) throw new Exception("Mismatch in events count! Expected " + expected.Length + ", got " + events.Count); for(int i=0;i<expected.Length;i++) { if (events[i] != expected[i]) throw new Exception("Event " + i + " (" + expected[i] + ") mismatched!"); } Console.WriteLine("All tests successful"); Console.ReadKey(); server.Shutdown("App exiting"); client.Shutdown("App exiting"); }
void ExecuteClientMessage(client_t cl, NetBuffer buf) { int serverId = buf.ReadInt32(); cl.messageAcknowledge = buf.ReadInt32(); if (cl.messageAcknowledge < 0) { // usually only hackers create messages like this // it is more annoying for them to let them hanging DropClient(cl, "Illegible client message"); return; } cl.reliableAcknowledge = buf.ReadInt32(); // NOTE: when the client message is fux0red the acknowledgement numbers // can be out of range, this could cause the server to send thousands of server // commands which the server thinks are not yet acknowledged in SV_UpdateServerCommandsToClient if (cl.reliableAcknowledge < cl.reliableSequence - 64) { DropClient(cl, "Illegible client message"); cl.reliableAcknowledge = cl.reliableSequence; return; } // if this is a usercmd from a previous gamestate, // ignore it or retransmit the current gamestate // if (serverId != sv.serverId && !cl.lastClientCommandString.Equals("nextdl")) { if (serverId >= sv.restartedServerId && serverId < sv.serverId) { // they just haven't caught the map_restart yet Common.Instance.WriteLine("{0} : ignoring pre map_restart / outdated client message", cl.name); return; } // if we can tell that the client has dropped the last // gamestate we sent them, resend it if (cl.messageAcknowledge > cl.gamestateMessageNum) { Common.Instance.WriteLine("{0} : dropped gamestate, resending", cl.name); SendClientGameState(cl); } return; } // this client has acknowledged the new gamestate so it's // safe to start sending it the real time again if (cl.oldServerTime > 0 && serverId == sv.serverId) { Common.Instance.WriteLine("{0} acknowledged gamestate", cl.name); cl.oldServerTime = 0; } // read optional clientCommand strings int c; do { c = buf.ReadByte(); if (c == (int)clc_ops_e.clc_EOF) break; if (c != (int)clc_ops_e.clc_clientCommand) break; if (!ClientCommand(cl, buf)) break; // we couldn't execute it because of the flood protection if (cl.state == clientState_t.CS_ZOMBIE) return; // disconnect command } while (true); // read the usercmd_t if (c == (int)clc_ops_e.clc_move) { UserMove(cl, buf, true); } else if (c == (int)clc_ops_e.clc_moveNoDelta) { UserMove(cl, buf, false); } else if (c != (int)clc_ops_e.clc_EOF) { Common.Instance.WriteLine("WARNING: bad command byte for client {0}", cl.name); } }