public static void ReadDynamics(PacketReader stream) { Logger.Log("Read dynamic instances: {0} Bytes.", stream.Length); int decomp = stream.ReadInt(); byte[] data = new byte[decomp]; using (var ms = new System.IO.MemoryStream(stream.GetRemainingData())) using (var ds = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Decompress)) { ds.Read(data, 0, decomp); } stream.Load(data, decomp); // Read models if (stream.ReadBit()) { int count = stream.ReadUShort(); for (int i = 0; i < count; i++) { ModelInstance model = ScriptManager.Interface.CreateModelInstance(); model.ReadStream(stream); model.ScriptObject.Create(); } } // Read vob instances if (stream.ReadBit()) { int count = stream.ReadUShort(); for (int i = 0; i < count; i++) { byte type = stream.ReadByte(); BaseVobInstance inst = ScriptManager.Interface.CreateInstance(type); inst.ReadStream(stream); inst.ScriptObject.Create(); } } }
internal static void Update() { int counter = 0; ServerMessages msgType; Packet packet; // Receive packets while ((packet = clientInterface.Receive()) != null) { try { receivedBytes += packet.length; packetReader.Load(packet.data, (int)packet.length); msgType = (ServerMessages)packetReader.ReadByte(); ReadMessage(msgType, packetReader); counter++; if (counter >= 1000) { counter = 0; Logger.Log("1000 Pakete hintereinander"); } } catch (Exception e) { if (packet.length >= 1) { Logger.LogError("{0}: {1}: {2}\n{3}", (ServerMessages)packet.data[0], e.Source, e.Message, e.StackTrace); } else { Logger.LogError("{0}: {1}\n{2}", e.Source, e.Message, e.StackTrace); } } finally { clientInterface.DeallocatePacket(packet); } } #region Debug Info // update only every second if (infoTimer.IsReady) { int ping = clientInterface.GetLastPing(clientInterface.GetSystemAddressFromIndex(0)); if (isDisconnected) { abortInfo.Texts[0].Text = "Verbindung geschlossen!"; abortInfo.Show(); } else if (isConnected) { if (ping > 300 || ping < 0) { abortInfo.Show(); } else { abortInfo.Hide(); } } // update ping text on screen int devIndex = 0; GUCVisualText pingText = devInfo.Texts[devIndex++]; pingText.Text = string.Format("Ping: {0}ms", ping); ColorRGBA color; if (ping <= 120) { color = new ColorRGBA((byte)(40 + 180 * ping / 120), 220, 40); } else if (ping <= 220) { color = new ColorRGBA(220, (byte)(220 - 180 * (ping - 100) / 120), 40); } else { color = new ColorRGBA(220, 40, 40); } pingText.SetColor(color); long fps = Hooks.hGame.LastElapsedTicks > 0 ? TimeSpan.TicksPerSecond / Hooks.hGame.LastElapsedTicks : 999; GUCVisualText fpsText = devInfo.Texts[devIndex++]; fpsText.Text = "FPS: " + fps; if (fps < 10) { color = new ColorRGBA(220, 40, 40); } else if (fps < 40) { color = new ColorRGBA(220, (byte)(40 + 180 * (fps - 10) / 30), 40); } else if (fps < 90) { color = new ColorRGBA((byte)(220 - 180 * (fps - 40) / 50), 220, 40); } else { color = new ColorRGBA(40, 220, 40); } fpsText.SetColor(color); devInfo.Texts[devIndex++].Text = "Spike: " + Hooks.hGame.SpikeLongest / TimeSpan.TicksPerMillisecond + "ms"; // update kB/s text on screen int kbs = (int)(receivedBytes); devInfo.Texts[devIndex++].Text = ("Net received: " + kbs + "B/s"); kbs = (int)(sentBytes); devInfo.Texts[devIndex++].Text = ("Net Sent: " + kbs + "B/s"); receivedBytes = 0; sentBytes = 0; if (World.Current != null) { devIndex = 8; devInfo.Texts[devIndex++].Text = World.Current.VobCount + " Vobs"; devInfo.Texts[devIndex++].Text = Client.guidedIDs.Count + " guided"; devInfo.Texts[devIndex++].Text = "Weather: " + World.Current.WeatherCtrl.CurrentWeight + " " + World.Current.Clock.Time.ToString(false); devInfo.Texts[devIndex++].Text = "Barrier: " + World.Current.BarrierCtrl.CurrentWeight + " " + World.Current.BarrierCtrl.EndWeight; devInfo.Texts[devIndex++].Text = "VobSounds: " + SoundHandler.VobSoundCount; devInfo.Texts[devIndex++].Text = "PosSounds: " + SoundHandler.PosSoundCount; //if (NPC.Hero != null) // devInfo.Texts[devIndex++].Text = NPC.Hero.Movement.ToString(); } } #endregion }
/** * Game loop which receives data from clients and redirects/reacts accordingly. * In this surrounding loop data is received from individual clients and the server reacts depending * on the network message types (see class attributes for these types). This is done for each * network message received by individual clients until there is no more (buffered) message * left. */ internal static void Update() { GameClient client = null; Packet packet; while ((packet = ServerInterface.Receive()) != null) { try { clientDict.TryGetValue(packet.guid.g, out client); pktReader.Load(packet.data, (int)packet.length); ClientMessages id = (ClientMessages)pktReader.ReadByte(); switch (id) { case ClientMessages.RakNet_ConnectionLost: case ClientMessages.RakNet_DisconnectionNotification: if (client != null) { Logger.Log("Client disconnected: {0} IP: {1}", client.ID, client.SystemAddress); DisconnectClient(client); } else { ServerInterface.CloseConnection(packet.guid, false); //just to be sure } break; case ClientMessages.RakNet_NewIncomingConnection: if (client != null) //there is already someone with this GUID. Should never happen. { throw new Exception("Duplicate RakNet-GUID! " + packet.guid); } else { Logger.Log("Client connected: IP: " + packet.systemAddress); } break; default: if (client == null) { if (id == ClientMessages.ConnectionMessage) //sends mac & drive string, should always be sent first { if (GameClient.Messages.ReadConnection(pktReader, packet.guid, packet.systemAddress, out client)) { clientDict.Add(client.Guid.g, client); client.Create(); } else { Logger.LogWarning("Client was not allowed to connect: {0}", packet.systemAddress); ServerInterface.CloseConnection(packet.guid, false); } } else { Logger.LogWarning("Client sent {0} before ConnectionMessage. Kicked IP: {1}", id, packet.systemAddress); ServerInterface.CloseConnection(packet.guid, false); } } else { if (id > ClientMessages.ScriptMessage && !client.IsIngame) { //Logger.LogWarning("Client sent {0} without being ingame. Kicked: {1} IP:{2}", msgID, p.guid, p.systemAddress); //DisconnectClient(client); break; } else { ReadUserMessage(id, client, pktReader); } } break; } } catch (Exception e) { if (packet.length > 0) { Logger.LogError("{0}: {1}: {2}\n{3}", (ClientMessages)packet.data[0], e.Source, e.Message, e.StackTrace); } else { Logger.LogError("{0}: {1}\n{2}", e.Source, e.Message, e.StackTrace); } if (client == null) { ServerInterface.CloseConnection(packet.guid, false); } else { DisconnectClient(client); } } finally { ServerInterface.DeallocatePacket(packet); } } }