public virtual void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime) { if (GameMain.Server != null) { return; } switch (type) { case ServerNetObject.ENTITY_POSITION: bool facingRight = AnimController.Dir > 0.0f; lastRecvPositionUpdateTime = (float)NetTime.Now; AnimController.Frozen = false; Enabled = true; UInt16 networkUpdateID = 0; if (msg.ReadBoolean()) { networkUpdateID = msg.ReadUInt16(); } else { bool aimInput = msg.ReadBoolean(); keys[(int)InputType.Aim].Held = aimInput; keys[(int)InputType.Aim].SetState(false, aimInput); bool useInput = msg.ReadBoolean(); keys[(int)InputType.Use].Held = useInput; keys[(int)InputType.Use].SetState(false, useInput); bool hasAttackLimb = msg.ReadBoolean(); if (hasAttackLimb) { bool attackInput = msg.ReadBoolean(); keys[(int)InputType.Attack].Held = attackInput; keys[(int)InputType.Attack].SetState(false, attackInput); } if (aimInput) { double aimAngle = ((double)msg.ReadUInt16() / 65535.0) * 2.0 * Math.PI; cursorPosition = (ViewTarget == null ? AnimController.Collider.Position : ViewTarget.Position) + new Vector2((float)Math.Cos(aimAngle), (float)Math.Sin(aimAngle)) * 60.0f; TransformCursorPos(); } facingRight = msg.ReadBoolean(); } bool entitySelected = msg.ReadBoolean(); Entity selectedEntity = null; AnimController.Animation animation = AnimController.Animation.None; if (entitySelected) { ushort entityID = msg.ReadUInt16(); selectedEntity = FindEntityByID(entityID); if (selectedEntity is Character) { bool doingCpr = msg.ReadBoolean(); if (doingCpr && selectedCharacter != null) { animation = AnimController.Animation.CPR; } } } Vector2 pos = new Vector2( msg.ReadFloat(), msg.ReadFloat()); int index = 0; if (GameMain.NetworkMember.Character == this && AllowInput) { var posInfo = new CharacterStateInfo(pos, networkUpdateID, facingRight ? Direction.Right : Direction.Left, selectedEntity, animation); while (index < memState.Count && NetIdUtils.IdMoreRecent(posInfo.ID, memState[index].ID)) { index++; } memState.Insert(index, posInfo); } else { var posInfo = new CharacterStateInfo(pos, sendingTime, facingRight ? Direction.Right : Direction.Left, selectedEntity, animation); while (index < memState.Count && posInfo.Timestamp > memState[index].Timestamp) { index++; } memState.Insert(index, posInfo); } break; case ServerNetObject.ENTITY_EVENT: int eventType = msg.ReadRangedInteger(0, 2); switch (eventType) { case 0: inventory.ClientRead(type, msg, sendingTime); break; case 1: byte ownerID = msg.ReadByte(); ResetNetState(); if (ownerID == GameMain.Client.ID) { if (controlled != null) { LastNetworkUpdateID = controlled.LastNetworkUpdateID; } controlled = this; IsRemotePlayer = false; GameMain.Client.Character = this; } else if (controlled == this) { controlled = null; IsRemotePlayer = ownerID > 0; } break; case 2: ReadStatus(msg); break; } break; } }
//static because we may need to instantiate the campaign if it hasn't been done yet public static void ClientRead(NetBuffer msg) { byte campaignID = msg.ReadByte(); UInt16 updateID = msg.ReadUInt16(); UInt16 saveID = msg.ReadUInt16(); string mapSeed = msg.ReadString(); UInt16 currentLocIndex = msg.ReadUInt16(); UInt16 selectedLocIndex = msg.ReadUInt16(); int money = msg.ReadInt32(); UInt16 purchasedItemCount = msg.ReadUInt16(); List <PurchasedItem> purchasedItems = new List <PurchasedItem>(); for (int i = 0; i < purchasedItemCount; i++) { UInt16 itemPrefabIndex = msg.ReadUInt16(); UInt16 itemQuantity = msg.ReadUInt16(); purchasedItems.Add(new PurchasedItem(MapEntityPrefab.List[itemPrefabIndex] as ItemPrefab, itemQuantity)); } MultiPlayerCampaign campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign; if (campaign == null || campaignID != campaign.CampaignID) { string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer); GameMain.GameSession = new GameSession(null, savePath, GameModePreset.list.Find(g => g.Name == "Campaign")); campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode); campaign.CampaignID = campaignID; campaign.GenerateMap(mapSeed); } GameMain.NetLobbyScreen.ToggleCampaignMode(true); if (NetIdUtils.IdMoreRecent(campaign.lastUpdateID, updateID)) { return; } //server has a newer save file if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID)) { /*//stop any active campaign save transfers, they're outdated now * List<FileReceiver.FileTransferIn> saveTransfers = * GameMain.Client.FileReceiver.ActiveTransfers.FindAll(t => t.FileType == FileTransferType.CampaignSave); * * foreach (var transfer in saveTransfers) * { * GameMain.Client.FileReceiver.StopTransfer(transfer); * } * * GameMain.Client.RequestFile(FileTransferType.CampaignSave, null, null);*/ campaign.PendingSaveID = saveID; } //we've got the latest save file else if (!NetIdUtils.IdMoreRecent(saveID, campaign.lastSaveID)) { campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex); campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex); campaign.Money = money; campaign.CargoManager.SetPurchasedItems(purchasedItems); campaign.lastUpdateID = updateID; } }
public virtual void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { if (GameMain.Server == null) { return; } switch (type) { case ClientNetObject.CHARACTER_INPUT: if (c.Character != this) { #if DEBUG DebugConsole.Log("Received a character update message from a client who's not controlling the character"); #endif return; } UInt16 networkUpdateID = msg.ReadUInt16(); byte inputCount = msg.ReadByte(); if (AllowInput) { Enabled = true; } for (int i = 0; i < inputCount; i++) { InputNetFlags newInput = (InputNetFlags)msg.ReadRangedInteger(0, (int)InputNetFlags.MaxVal); UInt16 newAim = 0; UInt16 newInteract = 0; if (newInput.HasFlag(InputNetFlags.Aim)) { newAim = msg.ReadUInt16(); } if (newInput.HasFlag(InputNetFlags.Select) || newInput.HasFlag(InputNetFlags.Use)) { newInteract = msg.ReadUInt16(); } if (AllowInput) { if (NetIdUtils.IdMoreRecent((ushort)(networkUpdateID - i), LastNetworkUpdateID) && (i < 60)) { NetInputMem newMem = new NetInputMem(); newMem.states = newInput; newMem.intAim = newAim; newMem.interact = newInteract; newMem.networkUpdateID = (ushort)(networkUpdateID - i); memInput.Insert(i, newMem); } } } if (NetIdUtils.IdMoreRecent(networkUpdateID, LastNetworkUpdateID)) { LastNetworkUpdateID = networkUpdateID; } if (memInput.Count > 60) { //deleting inputs from the queue here means the server is way behind and data needs to be dropped //we'll make the server drop down to 30 inputs for good measure memInput.RemoveRange(30, memInput.Count - 30); } break; case ClientNetObject.ENTITY_STATE: int eventType = msg.ReadRangedInteger(0, 2); switch (eventType) { case 0: inventory.ServerRead(type, msg, c); break; case 1: if (c.Character != this) { #if DEBUG DebugConsole.Log("Received a character update message from a client who's not controlling the character"); #endif return; } bool doingCPR = msg.ReadBoolean(); AnimController.Anim = doingCPR ? AnimController.Animation.CPR : AnimController.Animation.None; break; case 2: if (c.Character != this) { #if DEBUG DebugConsole.Log("Received a character update message from a client who's not controlling the character"); #endif return; } if (IsUnconscious) { Kill(lastAttackCauseOfDeath); } break; } msg.ReadPadBits(); break; } }
private void ReadStatus(NetBuffer msg) { bool isDead = msg.ReadBoolean(); if (isDead) { causeOfDeath = (CauseOfDeath)msg.ReadByte(); byte severedLimbCount = msg.ReadByte(); if (!IsDead) { if (causeOfDeath == CauseOfDeath.Pressure) { Implode(true); } else { Kill(causeOfDeath, true); } } for (int i = 0; i < severedLimbCount; i++) { int severedJointIndex = msg.ReadByte(); AnimController.SeverLimbJoint(AnimController.LimbJoints[severedJointIndex]); } } else { this.isDead = false; health = msg.ReadRangedSingle(minHealth, maxHealth, 8); bool lowOxygen = msg.ReadBoolean(); if (lowOxygen) { Oxygen = msg.ReadRangedSingle(-100.0f, 100.0f, 8); } else { Oxygen = 100.0f; } bool isBleeding = msg.ReadBoolean(); if (isBleeding) { bleeding = msg.ReadRangedSingle(0.0f, 5.0f, 8); } else { bleeding = 0.0f; } bool stunned = msg.ReadBoolean(); if (stunned) { float newStunTimer = msg.ReadRangedSingle(0.0f, 60.0f, 8); SetStun(newStunTimer, true, true); } else { SetStun(0.0f, true, true); } bool ragdolled = msg.ReadBoolean(); IsRagdolled = ragdolled; bool huskInfected = msg.ReadBoolean(); if (huskInfected) { HuskInfectionState = Math.Max(HuskInfectionState, 0.01f); } else { HuskInfectionState = 0.0f; } } }
public void Read(NetBuffer msg) { long oldPos = msg.Position; UInt32 size = msg.ReadVariableUInt32(); float x; float y; float z; float w; byte r; byte g; byte b; byte a; int ix; int iy; int width; int height; switch (typeString) { case "float": if (size != 4) { break; } property.SetValue(serverSettings, msg.ReadFloat()); return; case "vector2": if (size != 8) { break; } x = msg.ReadFloat(); y = msg.ReadFloat(); property.SetValue(serverSettings, new Vector2(x, y)); return; case "vector3": if (size != 12) { break; } x = msg.ReadFloat(); y = msg.ReadFloat(); z = msg.ReadFloat(); property.SetValue(serverSettings, new Vector3(x, y, z)); return; case "vector4": if (size != 16) { break; } x = msg.ReadFloat(); y = msg.ReadFloat(); z = msg.ReadFloat(); w = msg.ReadFloat(); property.SetValue(serverSettings, new Vector4(x, y, z, w)); return; case "color": if (size != 4) { break; } r = msg.ReadByte(); g = msg.ReadByte(); b = msg.ReadByte(); a = msg.ReadByte(); property.SetValue(serverSettings, new Color(r, g, b, a)); return; case "rectangle": if (size != 16) { break; } ix = msg.ReadInt32(); iy = msg.ReadInt32(); width = msg.ReadInt32(); height = msg.ReadInt32(); property.SetValue(serverSettings, new Rectangle(ix, iy, width, height)); return; default: msg.Position = oldPos; //reset position to properly read the string string incVal = msg.ReadString(); property.TrySetValue(serverSettings, incVal); return; } //size didn't match: skip this msg.Position += 8 * size; }
public void Deserialize(NetBuffer reader) { GlobalObjectId.ReadFrom(reader); NetworkObjectId = reader.ReadObjectId(); ObjectRole = (ObjectRole)reader.ReadByte(); }
public static Character ReadSpawnData(NetBuffer inc, bool spawn = true) { DebugConsole.NewMessage("READING CHARACTER SPAWN DATA", Color.Cyan); if (GameMain.Server != null) { return(null); } bool noInfo = inc.ReadBoolean(); ushort id = inc.ReadUInt16(); string configPath = inc.ReadString(); Vector2 position = new Vector2(inc.ReadFloat(), inc.ReadFloat()); bool enabled = inc.ReadBoolean(); DebugConsole.Log("Received spawn data for " + configPath); Character character = null; if (noInfo) { if (!spawn) { return(null); } character = Character.Create(configPath, position, null, true); character.ID = id; } else { bool hasOwner = inc.ReadBoolean(); int ownerId = hasOwner ? inc.ReadByte() : -1; string newName = inc.ReadString(); byte teamID = inc.ReadByte(); bool hasAi = inc.ReadBoolean(); bool isFemale = inc.ReadBoolean(); int headSpriteID = inc.ReadByte(); string jobName = inc.ReadString(); JobPrefab jobPrefab = null; Dictionary <string, int> skillLevels = new Dictionary <string, int>(); if (!string.IsNullOrEmpty(jobName)) { jobPrefab = JobPrefab.List.Find(jp => jp.Name == jobName); int skillCount = inc.ReadByte(); for (int i = 0; i < skillCount; i++) { string skillName = inc.ReadString(); int skillLevel = inc.ReadRangedInteger(0, 100); skillLevels.Add(skillName, skillLevel); } } if (!spawn) { return(null); } CharacterInfo ch = new CharacterInfo(configPath, newName, isFemale ? Gender.Female : Gender.Male, jobPrefab); ch.HeadSpriteId = headSpriteID; System.Diagnostics.Debug.Assert(skillLevels.Count == ch.Job.Skills.Count); if (ch.Job != null) { foreach (KeyValuePair <string, int> skill in skillLevels) { Skill matchingSkill = ch.Job.Skills.Find(s => s.Name == skill.Key); if (matchingSkill == null) { DebugConsole.ThrowError("Skill \"" + skill.Key + "\" not found in character \"" + newName + "\""); continue; } matchingSkill.Level = skill.Value; } } character = Create(configPath, position, ch, GameMain.Client.ID != ownerId, hasAi); character.ID = id; character.TeamID = teamID; if (GameMain.Client.ID == ownerId) { GameMain.Client.Character = character; Controlled = character; GameMain.LightManager.LosEnabled = true; character.memInput.Clear(); character.memState.Clear(); character.memLocalState.Clear(); } else { var ownerClient = GameMain.Client.ConnectedClients.Find(c => c.ID == ownerId); if (ownerClient != null) { ownerClient.Character = character; } } if (configPath == Character.HumanConfigFile) { GameMain.GameSession.CrewManager.AddCharacter(character); } } character.Enabled = Controlled == character || enabled; return(character); }
public NetworkMasterMessage(NetBuffer buffer) { stream = new BitStream(buffer, false); internCode = (InternalCode)buffer.ReadByte(); }
private void ReadStatus(NetBuffer msg) { if (GameMain.Server != null) { DebugConsole.ThrowError("Server attempted to read character status from a networked message"); return; } bool isDead = msg.ReadBoolean(); if (isDead) { causeOfDeath = (CauseOfDeath)msg.ReadByte(); byte severedLimbCount = msg.ReadByte(); if (causeOfDeath == CauseOfDeath.Pressure) { Implode(true); } else { Kill(causeOfDeath, true); } for (int i = 0; i < severedLimbCount; i++) { int severedJointIndex = msg.ReadByte(); AnimController.SeverLimbJoint(AnimController.LimbJoints[severedJointIndex]); } } else { health = msg.ReadRangedSingle(minHealth, maxHealth, 8); bool lowOxygen = msg.ReadBoolean(); if (lowOxygen) { Oxygen = msg.ReadRangedSingle(-100.0f, 100.0f, 8); } else { Oxygen = 100.0f; } bool isBleeding = msg.ReadBoolean(); if (isBleeding) { bleeding = msg.ReadRangedSingle(0.0f, 5.0f, 8); } else { bleeding = 0.0f; } bool stunned = msg.ReadBoolean(); if (stunned) { float newStunTimer = msg.ReadRangedSingle(0.0f, 60.0f, 8); SetStun(newStunTimer, true, true); } else { SetStun(0.0f, true, true); } bool huskInfected = msg.ReadBoolean(); if (huskInfected) { HuskInfectionState = Math.Max(HuskInfectionState, 0.01f); } else { HuskInfectionState = 0.0f; } } }
private bool ReceiveUserMessage(NetBuffer msg, NetworkMachine originMachine) { byte senderId, recipientId; SendDataOptions options; int length; Packet packet; try { senderId = msg.ReadByte(); recipientId = msg.ReadByte(); options = (SendDataOptions)msg.ReadByte(); length = msg.ReadInt32(); packet = packetPool.Get(length); // Critical TODO: Protect memory msg.ReadBytes(packet.data, 0, length); } catch { return(false); } bool sendToAll = recipientId == 255; if (senderId == 255) { return(false); } var sender = gamerFromId.ContainsKey(senderId) ? gamerFromId[senderId] : null; // Sender can be null if gamer joined not yet received if (sender != null && sender.machine != originMachine) { return(false); } if (!IsSendDataOptionsValid(options)) { return(false); } if (sendToAll) { bool firstGamer = true; foreach (var localGamer in localGamers) { var uniquePacket = firstGamer ? packet : packetPool.GetAndFillWith(packet.data); if (!localGamer.AddInboundPacket(uniquePacket, senderId, options)) { // TODO: Kick machine if host? Debug.WriteLine("MaxDelayedInboundPacketsAllowed reached!"); return(false); } firstGamer = false; } return(true); } else { var recipient = FindGamerById(recipientId); if (recipient == null) { // TODO: Check if recipient is on list of previous gamers, for now assume true bool previousGamer = true; // Message is ok if the recipient was a gamer previously return(previousGamer); } var localGamer = recipient as LocalNetworkGamer; if (localGamer == null) { if (isHost) { // The message is meant for someone else (return true so that the message is forwarded) return(true); } else { // The message is meant for us but the local gamer is gone? The host made a mistake or our local gamer left, see above bool previousLocalGamer = true; return(previousLocalGamer); } } if (!localGamer.AddInboundPacket(packet, senderId, options)) { // TODO: Kick machine if host? Debug.WriteLine("MaxDelayedInboundPacketsAllowed reached!"); return(false); } return(true); } }
private bool ReceiveGamerJoined(NetBuffer msg, NetworkMachine originMachine, NetworkMachine recipientMachine) { byte id; string displayName, gamertag; bool isPrivateSlot, isReady; try { id = msg.ReadByte(); displayName = msg.ReadString(); gamertag = msg.ReadString(); isPrivateSlot = msg.ReadBoolean(); isReady = msg.ReadBoolean(); } catch { return(false); } if (id == 255) { return(false); } if (originMachine.isLocal) { // Already added local gamer return(true); } if (isHost) { if (!gamerFromId.ContainsKey(id)) { // Host must know about all gamers return(false); } if (id == 0) { // Someone is impersonating the host gamer return(false); } if (recipientMachine == null || recipientMachine == localMachine) { // Host already added gamer, just update it and add it to the game var gamer = gamerFromId[id]; if (gamer.state != NetworkGamerState.Pending) { return(false); } gamer.DisplayName = displayName; gamer.Gamertag = gamertag; gamer.isPrivateSlot = isPrivateSlot; gamer.isReady = isReady; AddGamer(gamer); } else { // TODO: Make sure client is not spamming recipient } } else { if (id == 0) { // Special case for host gamer if (!originMachine.isHost) { return(false); } // Already added host gamer with id 0, just update it Host.DisplayName = displayName; Host.Gamertag = gamertag; Host.isPrivateSlot = isPrivateSlot; Host.isReady = isReady; } else { AddGamer(new NetworkGamer(originMachine, id, isPrivateSlot, isReady, displayName, gamertag)); } } return(true); }
private void ReceiveMessage(NetBuffer msg, NetDeliveryMethod deliveryMethod, NetworkMachine senderMachine) { // Decode header if (msg.LengthBytes < 3) { // TODO: Kick machine? Debug.Write("Received empty message from machine " + senderMachine.id); return; } //ushort header0, header1; byte headerMsgType, headerRecipientId, headerOriginId; try { headerMsgType = msg.ReadByte(); headerRecipientId = msg.ReadByte(); headerOriginId = msg.ReadByte(); } catch { // TODO: Kick machine? Debug.WriteLine("Received message with malformed header from machine " + senderMachine.id); return; } if (headerMsgType >= MessageTypeCount) { // TODO: Kick machine? Debug.WriteLine("Received message with malformed header from machine " + senderMachine.id); return; } MessageType msgType = (MessageType)headerMsgType; bool sendToAll = headerRecipientId == 255; if ((!sendToAll && !machineFromId.ContainsKey(headerRecipientId)) || !machineFromId.ContainsKey(headerOriginId)) { if (isHost) { // TODO: Kick machine? Debug.WriteLine("Received message with malformed header from machine " + senderMachine.id); } return; } var recipientMachine = sendToAll ? null : machineFromId[headerRecipientId]; var originMachine = machineFromId[headerOriginId]; if (isHost && senderMachine != originMachine) { // TODO: Kick machine? Debug.WriteLine("Received message with malformed header from machine " + senderMachine.id); return; } if (msgType != MessageType.User) { Debug.WriteLine("R " + senderMachine.id + "(" + originMachine.id + ")->" + (recipientMachine != null ? recipientMachine.id.ToString() : "[all]") + " " + msgType); } // Handle message bool success = false; switch (msgType) { case MessageType.SessionStateChanged: success = ReceiveSessionStateChanged(msg, originMachine); break; case MessageType.MachineConnected: success = ReceiveMachineConnectedMessage(msg, originMachine); break; case MessageType.MachineDisconnected: success = ReceiveMachineDisconnectedMessage(msg, originMachine); break; case MessageType.GamerIdRequest: success = ReceiveGamerIdRequest(msg, originMachine); break; case MessageType.GamerIdResponse: success = ReceiveGamerIdResponse(msg, originMachine); break; case MessageType.GamerJoined: success = ReceiveGamerJoined(msg, originMachine, recipientMachine); break; case MessageType.GamerLeft: success = ReceiveGamerLeft(msg, originMachine); break; case MessageType.GamerStateChanged: success = ReceiveGamerStateChanged(msg, originMachine); break; case MessageType.ResetReady: success = ReceiveResetReady(msg, originMachine); break; case MessageType.StartGame: success = ReceiveStartGame(msg, originMachine); break; case MessageType.EndGame: success = ReceiveEndGame(msg, originMachine); break; case MessageType.User: success = ReceiveUserMessage(msg, originMachine); break; default: throw new NotImplementedException(); } if (!success) { // TODO: Kick machine if host and disconnect if client? Debug.WriteLine("Failed to parse last message!"); return; } // If host, forward message to peers if (isHost && senderMachine != localMachine && recipientMachine != localMachine) { if (msgType != MessageType.User) { Debug.WriteLine("Forwarding " + msgType + " message to machine " + (recipientMachine != null ? recipientMachine.id.ToString() : "[all]")); } SendMessage(CreateMessageFrom(msg), deliveryMethod, ignoreSelf: true); } }