private void ApplyRemoteState(IReadMessage msg) { List <Wire> prevWires = Connections.SelectMany(c => c.Wires.Where(w => w != null)).ToList(); List <Wire> newWires = new List <Wire>(); ushort userID = msg.ReadUInt16(); if (userID == 0) { user = null; } else { user = Entity.FindEntityByID(userID) as Character; base.IsActive = true; } foreach (Connection connection in Connections) { connection.ClearConnections(); } foreach (Connection connection in Connections) { for (int i = 0; i < connection.MaxWires; i++) { ushort wireId = msg.ReadUInt16(); if (!(Entity.FindEntityByID(wireId) is Item wireItem)) { continue; } Wire wireComponent = wireItem.GetComponent <Wire>(); if (wireComponent == null) { continue; } newWires.Add(wireComponent); connection.SetWire(i, wireComponent); wireComponent.Connect(connection, false); } } List <Wire> previousDisconnectedWires = new List <Wire>(DisconnectedWires); DisconnectedWires.Clear(); ushort disconnectedWireCount = msg.ReadUInt16(); for (int i = 0; i < disconnectedWireCount; i++) { ushort wireId = msg.ReadUInt16(); if (!(Entity.FindEntityByID(wireId) is Item wireItem)) { continue; } Wire wireComponent = wireItem.GetComponent <Wire>(); if (wireComponent == null) { continue; } DisconnectedWires.Add(wireComponent); base.IsActive = true; } foreach (Wire wire in prevWires) { bool connected = wire.Connections[0] != null || wire.Connections[1] != null; if (!connected) { foreach (Item item in Item.ItemList) { var connectionPanel = item.GetComponent <ConnectionPanel>(); if (connectionPanel != null && connectionPanel.DisconnectedWires.Contains(wire)) { connected = true; break; } } } if (wire.Item.ParentInventory == null && !connected) { wire.Item.Drop(null); } } foreach (Wire disconnectedWire in previousDisconnectedWires) { if (disconnectedWire.Connections[0] == null && disconnectedWire.Connections[1] == null && !DisconnectedWires.Contains(disconnectedWire)) { disconnectedWire.Item.Drop(dropper: null); } } }
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { List <Wire>[] wires = new List <Wire> [Connections.Count]; //read wire IDs for each connection for (int i = 0; i < Connections.Count; i++) { wires[i] = new List <Wire>(); for (int j = 0; j < Connection.MaxLinked; j++) { ushort wireId = msg.ReadUInt16(); if (!(Entity.FindEntityByID(wireId) is Item wireItem)) { continue; } Wire wireComponent = wireItem.GetComponent <Wire>(); if (wireComponent != null) { wires[i].Add(wireComponent); } } } List <Wire> clientSideDisconnectedWires = new List <Wire>(); ushort disconnectedWireCount = msg.ReadUInt16(); for (int i = 0; i < disconnectedWireCount; i++) { ushort wireId = msg.ReadUInt16(); if (!(Entity.FindEntityByID(wireId) is Item wireItem)) { continue; } Wire wireComponent = wireItem.GetComponent <Wire>(); if (wireComponent == null) { continue; } clientSideDisconnectedWires.Add(wireComponent); } //don't allow rewiring locked panels if (Locked || !GameMain.NetworkMember.ServerSettings.AllowRewiring) { return; } item.CreateServerEvent(this); //check if the character can access this connectionpanel //and all the wires they're trying to connect if (!item.CanClientAccess(c)) { return; } for (int i = 0; i < Connections.Count; i++) { foreach (Wire wire in wires[i]) { //wire not found in any of the connections yet (client is trying to connect a new wire) // -> we need to check if the client has access to it if (!Connections.Any(connection => connection.Wires.Contains(wire)) && !DisconnectedWires.Contains(wire)) { if (!wire.Item.CanClientAccess(c)) { return; } } } } //go through existing wire links for (int i = 0; i < Connections.Count; i++) { int j = -1; foreach (Wire existingWire in Connections[i].Wires) { j++; if (existingWire == null) { continue; } //existing wire not in the list of new wires -> disconnect it if (!wires[i].Contains(existingWire)) { if (existingWire.Locked) { //this should not be possible unless the client is running a modified version of the game GameServer.Log(c.Character.LogName + " attempted to disconnect a locked wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.Error); continue; } existingWire.RemoveConnection(item); item.GetComponent <ConnectionPanel>()?.DisconnectedWires.Add(existingWire); GameMain.Server.KarmaManager.OnWireDisconnected(c.Character, existingWire); if (existingWire.Connections[0] == null && existingWire.Connections[1] == null) { GameServer.Log(c.Character.LogName + " disconnected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.ItemInteraction); if (!clientSideDisconnectedWires.Contains(existingWire)) { existingWire.Item.Drop(c.Character); } } else if (existingWire.Connections[0] != null) { GameServer.Log(c.Character.LogName + " disconnected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[0].Item.Name + " (" + existingWire.Connections[0].Name + ")", ServerLog.MessageType.ItemInteraction); //wires that are not in anyone's inventory (i.e. not currently being rewired) //can never be connected to only one connection // -> the client must have dropped the wire from the connection panel /*if (existingWire.Item.ParentInventory == null && !wires.Any(w => w.Contains(existingWire))) * { * //let other clients know the item was also disconnected from the other connection * existingWire.Connections[0].Item.CreateServerEvent(existingWire.Connections[0].Item.GetComponent<ConnectionPanel>()); * existingWire.Item.Drop(c.Character); * }*/ } else if (existingWire.Connections[1] != null) { GameServer.Log(c.Character.LogName + " disconnected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[1].Item.Name + " (" + existingWire.Connections[1].Name + ")", ServerLog.MessageType.ItemInteraction); /*if (existingWire.Item.ParentInventory == null && !wires.Any(w => w.Contains(existingWire))) * { * //let other clients know the item was also disconnected from the other connection * existingWire.Connections[1].Item.CreateServerEvent(existingWire.Connections[1].Item.GetComponent<ConnectionPanel>()); * existingWire.Item.Drop(c.Character); * }*/ } Connections[i].SetWire(j, null); } } } foreach (Wire disconnectedWire in DisconnectedWires.ToList()) { if (disconnectedWire.Connections[0] == null && disconnectedWire.Connections[1] == null && !clientSideDisconnectedWires.Contains(disconnectedWire)) { disconnectedWire.Item.Drop(c.Character); GameServer.Log(c.Character.LogName + " dropped " + disconnectedWire.Name, ServerLog.MessageType.Inventory); } } //go through new wires for (int i = 0; i < Connections.Count; i++) { foreach (Wire newWire in wires[i]) { //already connected, no need to do anything if (Connections[i].Wires.Contains(newWire)) { continue; } Connections[i].TryAddLink(newWire); newWire.Connect(Connections[i], true, true); var otherConnection = newWire.OtherConnection(Connections[i]); if (otherConnection == null) { GameServer.Log(c.Character.LogName + " connected a wire to " + Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.ItemInteraction); } else { GameServer.Log(c.Character.LogName + " connected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + (otherConnection == null ? "none" : otherConnection.Item.Name + " (" + (otherConnection.Name) + ")"), ServerLog.MessageType.ItemInteraction); } } } }
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { List <Wire>[] wires = new List <Wire> [Connections.Count]; //read wire IDs for each connection for (int i = 0; i < Connections.Count; i++) { wires[i] = new List <Wire>(); for (int j = 0; j < Connections[i].MaxWires; j++) { ushort wireId = msg.ReadUInt16(); if (!(Entity.FindEntityByID(wireId) is Item wireItem)) { continue; } Wire wireComponent = wireItem.GetComponent <Wire>(); if (wireComponent != null) { wires[i].Add(wireComponent); } } } List <Wire> clientSideDisconnectedWires = new List <Wire>(); ushort disconnectedWireCount = msg.ReadUInt16(); for (int i = 0; i < disconnectedWireCount; i++) { ushort wireId = msg.ReadUInt16(); if (!(Entity.FindEntityByID(wireId) is Item wireItem)) { continue; } Wire wireComponent = wireItem.GetComponent <Wire>(); if (wireComponent == null) { continue; } clientSideDisconnectedWires.Add(wireComponent); } //don't allow rewiring locked panels if (Locked || !GameMain.NetworkMember.ServerSettings.AllowRewiring) { return; } item.CreateServerEvent(this); //check if the character can access this connectionpanel //and all the wires they're trying to connect if (!item.CanClientAccess(c)) { return; } for (int i = 0; i < Connections.Count; i++) { foreach (Wire wire in wires[i]) { //wire not found in any of the connections yet (client is trying to connect a new wire) // -> we need to check if the client has access to it if (!Connections.Any(connection => connection.Wires.Contains(wire)) && !DisconnectedWires.Contains(wire)) { if (!wire.Item.CanClientAccess(c)) { return; } } } } if (!CheckCharacterSuccess(c.Character)) { item.CreateServerEvent(this); c.Character.Inventory?.CreateNetworkEvent(); foreach (Item heldItem in c.Character.HeldItems) { var selectedWire = heldItem?.GetComponent <Wire>(); if (selectedWire == null) { continue; } selectedWire.CreateNetworkEvent(); var panel1 = selectedWire.Connections[0]?.ConnectionPanel; if (panel1 != null && panel1 != this) { panel1.item.CreateServerEvent(panel1); } var panel2 = selectedWire.Connections[1]?.ConnectionPanel; if (panel2 != null && panel2 != this) { panel2.item.CreateServerEvent(panel2); } CoroutineManager.InvokeAfter(() => { item.CreateServerEvent(this); if (panel1 != null && panel1 != this) { panel1.item.CreateServerEvent(panel1); } if (panel2 != null && panel2 != this) { panel2.item.CreateServerEvent(panel2); } if (!selectedWire.Item.Removed) { selectedWire.CreateNetworkEvent(); } }, 1.0f); } GameMain.Server?.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFailure, this, c.Character.ID }); return; } //go through existing wire links for (int i = 0; i < Connections.Count; i++) { int j = -1; foreach (Wire existingWire in Connections[i].Wires) { j++; if (existingWire == null) { continue; } //existing wire not in the list of new wires -> disconnect it if (!wires[i].Contains(existingWire)) { if (existingWire.Locked) { //this should not be possible unless the client is running a modified version of the game GameServer.Log(GameServer.CharacterLogName(c.Character) + " attempted to disconnect a locked wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.Error); continue; } existingWire.RemoveConnection(item); if (existingWire.Item.ParentInventory == null) { item.GetComponent <ConnectionPanel>()?.DisconnectedWires.Add(existingWire); } if (!wires.Any(w => w.Contains(existingWire))) { GameMain.Server.KarmaManager.OnWireDisconnected(c.Character, existingWire); } if (existingWire.Connections[0] == null && existingWire.Connections[1] == null) { GameServer.Log(GameServer.CharacterLogName(c.Character) + " disconnected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.Wiring); if (existingWire.Item.ParentInventory != null) { //in an inventory and not connected to anything -> the wire cannot have any nodes existingWire.ClearConnections(); } else if (!clientSideDisconnectedWires.Contains(existingWire)) { //not in an inventory, not connected to anything, not hanging loose from any panel -> must be dropped existingWire.Item.Drop(c.Character); } } else if (existingWire.Connections[0] != null) { GameServer.Log(GameServer.CharacterLogName(c.Character) + " disconnected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[0].Item.Name + " (" + existingWire.Connections[0].Name + ")", ServerLog.MessageType.Wiring); //wires that are not in anyone's inventory (i.e. not currently being rewired) //can never be connected to only one connection // -> the client must have dropped the wire from the connection panel /*if (existingWire.Item.ParentInventory == null && !wires.Any(w => w.Contains(existingWire))) * { * //let other clients know the item was also disconnected from the other connection * existingWire.Connections[0].Item.CreateServerEvent(existingWire.Connections[0].Item.GetComponent<ConnectionPanel>()); * existingWire.Item.Drop(c.Character); * }*/ } else if (existingWire.Connections[1] != null) { GameServer.Log(GameServer.CharacterLogName(c.Character) + " disconnected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[1].Item.Name + " (" + existingWire.Connections[1].Name + ")", ServerLog.MessageType.Wiring); /*if (existingWire.Item.ParentInventory == null && !wires.Any(w => w.Contains(existingWire))) * { * //let other clients know the item was also disconnected from the other connection * existingWire.Connections[1].Item.CreateServerEvent(existingWire.Connections[1].Item.GetComponent<ConnectionPanel>()); * existingWire.Item.Drop(c.Character); * }*/ } Connections[i].SetWire(j, null); } } } foreach (Wire disconnectedWire in DisconnectedWires.ToList()) { if (disconnectedWire.Connections[0] == null && disconnectedWire.Connections[1] == null && !clientSideDisconnectedWires.Contains(disconnectedWire) && disconnectedWire.Item.ParentInventory == null) { disconnectedWire.Item.Drop(c.Character); GameServer.Log(GameServer.CharacterLogName(c.Character) + " dropped " + disconnectedWire.Name, ServerLog.MessageType.Inventory); } } //go through new wires for (int i = 0; i < Connections.Count; i++) { foreach (Wire newWire in wires[i]) { //already connected, no need to do anything if (Connections[i].Wires.Contains(newWire)) { continue; } Connections[i].TryAddLink(newWire); newWire.Connect(Connections[i], true, true); var otherConnection = newWire.OtherConnection(Connections[i]); if (otherConnection == null) { GameServer.Log(GameServer.CharacterLogName(c.Character) + " connected a wire to " + Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.Wiring); } else { GameServer.Log(GameServer.CharacterLogName(c.Character) + " connected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + (otherConnection == null ? "none" : otherConnection.Item.Name + " (" + (otherConnection.Name) + ")"), ServerLog.MessageType.Wiring); } } } }