From 5446f8095d7ba474fa901ece3f4c0435cfaecc81 Mon Sep 17 00:00:00 2001 From: Joshua Navarro Date: Sat, 15 Dec 2018 03:00:32 -0800 Subject: [PATCH] Massive fixing to NetCode to try to re-integrate custom objects in multiplayer. --- .../StardustCore/Animations/Animation.cs | 5 +- .../Animations/AnimationManager.cs | 15 +- GeneralMods/StardustCore/ModCore.cs | 17 +- .../NetCode/Graphics/NetAnimation.cs | 60 +++ .../NetCode/Graphics/NetAnimationManager.cs | 93 ++++ .../StardustCore/NetCode/ModdedClient.cs | 158 +++++++ .../StardustCore/NetCode/ModdedGameServer.cs | 427 ++++++++++++++++++ .../StardustCore/NetCode/NetAnimation.cs | 64 +++ .../NetCode/NetAnimationManager.cs | 126 ++++++ .../NetCode/NetBufferReadStream.cs | 99 ++++ .../NetCode/NetBufferWriteStream.cs | 97 ++++ .../StardustCore/NetCode/NetKeyValuePair.cs | 30 ++ .../NetPairs/NetVector2MultiTilePair.cs | 36 ++ .../NetCode/NetTexure2DExtended.cs | 78 ++++ .../NetCode/Objects/NetCoreObject.cs | 137 ++++++ .../NetCode/Objects/NetMultiTileComponent.cs | 116 +++++ .../NetCode/Objects/NetMultiTileObject.cs | 68 +++ .../StardustCore/Objects/CoreObject.cs | 17 +- .../Objects/MultiTileComponent.cs | 44 +- .../StardustCore/Objects/MultiTileObject.cs | 12 +- GeneralMods/StardustCore/StardustCore.csproj | 14 + 21 files changed, 1685 insertions(+), 28 deletions(-) create mode 100644 GeneralMods/StardustCore/NetCode/Graphics/NetAnimation.cs create mode 100644 GeneralMods/StardustCore/NetCode/Graphics/NetAnimationManager.cs create mode 100644 GeneralMods/StardustCore/NetCode/ModdedClient.cs create mode 100644 GeneralMods/StardustCore/NetCode/ModdedGameServer.cs create mode 100644 GeneralMods/StardustCore/NetCode/NetAnimation.cs create mode 100644 GeneralMods/StardustCore/NetCode/NetAnimationManager.cs create mode 100644 GeneralMods/StardustCore/NetCode/NetBufferReadStream.cs create mode 100644 GeneralMods/StardustCore/NetCode/NetBufferWriteStream.cs create mode 100644 GeneralMods/StardustCore/NetCode/NetKeyValuePair.cs create mode 100644 GeneralMods/StardustCore/NetCode/NetPairs/NetVector2MultiTilePair.cs create mode 100644 GeneralMods/StardustCore/NetCode/NetTexure2DExtended.cs create mode 100644 GeneralMods/StardustCore/NetCode/Objects/NetCoreObject.cs create mode 100644 GeneralMods/StardustCore/NetCode/Objects/NetMultiTileComponent.cs create mode 100644 GeneralMods/StardustCore/NetCode/Objects/NetMultiTileObject.cs diff --git a/GeneralMods/StardustCore/Animations/Animation.cs b/GeneralMods/StardustCore/Animations/Animation.cs index 6ef5fca3..a7d5fadc 100644 --- a/GeneralMods/StardustCore/Animations/Animation.cs +++ b/GeneralMods/StardustCore/Animations/Animation.cs @@ -30,11 +30,10 @@ namespace StardustCore.Animations [XmlIgnore] public NetFields NetFields { get; } = new NetFields(); - public Animation() { - sourceRectangle = new Rectangle(); - frameDuration = -1; + this.sourceRectangle = new Rectangle(); + this.frameDuration = -1; } /// diff --git a/GeneralMods/StardustCore/Animations/AnimationManager.cs b/GeneralMods/StardustCore/Animations/AnimationManager.cs index a93d818e..512ad4a1 100644 --- a/GeneralMods/StardustCore/Animations/AnimationManager.cs +++ b/GeneralMods/StardustCore/Animations/AnimationManager.cs @@ -54,10 +54,15 @@ namespace StardustCore.Animations this.animationDataString = animationString; this.animations = parseAnimationsFromXNB(animationString); bool f = animations.TryGetValue(startingAnimationKey, out currentAnimationList); - if (f == true) { + if (f == true) + { setAnimation(startingAnimationKey, startingAnimationFrame); } - else currentAnimation = this.defaultDrawFrame; + else + { + currentAnimation = this.defaultDrawFrame; + this.currentAnimationName = ""; + } } public AnimationManager(Texture2DExtended ObjectTexture, Animation DefaultFrame, Dictionary> animationString, string startingAnimationKey, int startingAnimationFrame = 0, bool EnabledByDefault = true) @@ -73,7 +78,11 @@ namespace StardustCore.Animations { setAnimation(startingAnimationKey, startingAnimationFrame); } - else currentAnimation = this.defaultDrawFrame; + else + { + currentAnimation = this.defaultDrawFrame; + this.currentAnimationName = ""; + } } /// diff --git a/GeneralMods/StardustCore/ModCore.cs b/GeneralMods/StardustCore/ModCore.cs index 3ba7bd83..780cfb99 100644 --- a/GeneralMods/StardustCore/ModCore.cs +++ b/GeneralMods/StardustCore/ModCore.cs @@ -168,19 +168,20 @@ namespace StardustCore { SerializationManager.restoreAllModObjects(SerializationManager.trackedObjectList); - //List> objs = new List>(); - /* - MultiTileComponent tile1 = new MultiTileComponent(0,"Tileobj1","A basic tile obj",new Texture2DExtended(ModCore.ModHelper, Path.Combine("Content", "Graphics", "MultiTest", "Test1.png"))); - MultiTileComponent tile2 = new MultiTileComponent(0,"Tileobj2", "A basic tile obj", new Texture2DExtended(ModCore.ModHelper, Path.Combine("Content", "Graphics", "MultiTest", "Test2.png"))); - MultiTileComponent tile3 = new MultiTileComponent(0,"Tileobj3", "A basic tile obj", new Texture2DExtended(ModCore.ModHelper, Path.Combine("Content", "Graphics", "MultiTest", "Test3.png"))); + + List> objs = new List>(); + + MultiTileComponent tile1 = new MultiTileComponent(0,"Tileobj1","A basic tile obj",new Texture2DExtended(ModCore.ModHelper,ModCore.Manifest ,Path.Combine("Content", "Graphics", "MultiTest", "Test1.png"))); + MultiTileComponent tile2 = new MultiTileComponent(0,"Tileobj2", "A basic tile obj", new Texture2DExtended(ModCore.ModHelper, ModCore.Manifest, Path.Combine("Content", "Graphics", "MultiTest", "Test2.png"))); + MultiTileComponent tile3 = new MultiTileComponent(0,"Tileobj3", "A basic tile obj", new Texture2DExtended(ModCore.ModHelper, ModCore.Manifest, Path.Combine("Content", "Graphics", "MultiTest", "Test3.png"))); objs.Add(new KeyValuePair(new Vector2(0, 0), tile1)); objs.Add(new KeyValuePair(new Vector2(1, 0), tile2)); objs.Add(new KeyValuePair(new Vector2(2, 0), tile3)); - MultiTileObject collection= new MultiTileObject("MultiTest", "Trying to get multi object testing working", Vector2.Zero, new Texture2DExtended(ModCore.ModHelper, Path.Combine("Content", "Graphics", "MultiTest", "Test3.png")), objs, StardustCore.IlluminateFramework.Colors.invertColor(StardustCore.IlluminateFramework.LightColorsList.Purple), "MultiTest"); - */ + MultiTileObject collection= new MultiTileObject("MultiTest", "Trying to get multi object testing working", Vector2.Zero, new Texture2DExtended(ModCore.ModHelper, ModCore.Manifest, Path.Combine("Content", "Graphics", "MultiTest", "Test3.png")), objs, StardustCore.IlluminateFramework.Colors.invertColor(StardustCore.IlluminateFramework.LightColorsList.Purple), "MultiTest"); + - // Game1.player.addItemToInventory(collection); + Game1.player.addItemToInventory(collection); /* CoreObject tile1 = new CoreObject(new Texture2DExtended(ModCore.ModHelper, Path.Combine("Content", "Graphics", "MultiTest", "Test1.png")),3, Vector2.Zero,9); diff --git a/GeneralMods/StardustCore/NetCode/Graphics/NetAnimation.cs b/GeneralMods/StardustCore/NetCode/Graphics/NetAnimation.cs new file mode 100644 index 00000000..da2d0c0c --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/Graphics/NetAnimation.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Netcode; +using StardustCore.Animations; + +namespace StardustCore.NetCode.Graphics +{ + public class NetAnimation : Netcode.NetField + { + + public NetRectangle sourceRect; + public NetInt frameDuration; + public NetInt frameDurationUntilNextAnimation; + + public NetAnimation() + { + + } + public NetAnimation(Animations.Animation animation) : base(animation) + { + + } + + public override void Set(Animation newValue) + { + throw new NotImplementedException(); + } + + protected override void ReadDelta(BinaryReader reader, NetVersion version) + { + sourceRect = new NetRectangle(); + sourceRect.Read(reader, version); + Value.sourceRectangle = sourceRect.Value; + + frameDuration = new NetInt(); + frameDuration.Read(reader, version); + Value.frameDuration = frameDuration.Value; + + frameDurationUntilNextAnimation = new NetInt(); + frameDurationUntilNextAnimation.Read(reader, version); + Value.frameDuration = frameDuration.Value; + } + + protected override void WriteDelta(BinaryWriter writer) + { + sourceRect = new NetRectangle(Value.sourceRectangle); + sourceRect.Write(writer); + + frameDuration = new NetInt(Value.frameDuration); + frameDuration.Write(writer); + + frameDurationUntilNextAnimation = new NetInt(Value.frameCountUntilNextAnimation); + frameDurationUntilNextAnimation.Write(writer); + } + } +} diff --git a/GeneralMods/StardustCore/NetCode/Graphics/NetAnimationManager.cs b/GeneralMods/StardustCore/NetCode/Graphics/NetAnimationManager.cs new file mode 100644 index 00000000..864a2823 --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/Graphics/NetAnimationManager.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Netcode; +using StardewValley; +using StardewValley.Network; +using StardustCore.Animations; + +namespace StardustCore.NetCode.Graphics +{ + public class NetAnimationManager : Netcode.NetField + { + + public NetAnimationManager() + { + + } + + public NetAnimationManager(Animations.AnimationManager manager): base(manager) + { + + } + + public override void Set(AnimationManager newValue) + { + throw new NotImplementedException(); + } + + protected override void ReadDelta(BinaryReader reader, NetVersion version) + { + NetString currentAnimationName = new NetString(); + currentAnimationName.Read(reader, version); + + NetInt currentIndex = new NetInt(); + currentIndex.Read(reader, version); + + NetTexture2DExtended text = new NetTexture2DExtended(); + text.Read(reader, version); + + NetAnimation defaultAnimation = new NetAnimation(); + defaultAnimation.Read(reader, version); + + NetBool enabled = new NetBool(); + enabled.Read(reader, version); + + NetString data = new NetString(); + data.Read(reader, version); + + Value.setExtendedTexture(text.Value); + Value.defaultDrawFrame = defaultAnimation.Value; + Value.enabled = enabled.Value; + //Try and prevent unnecessary parsing. + if (Value.animations == null && !String.IsNullOrEmpty(Value.animationDataString)) + { + Value.animations = Animations.AnimationManager.parseAnimationsFromXNB(data.Value); + } + if (!String.IsNullOrEmpty(data.Value)) + { + Value.setAnimation(currentAnimationName.Value, currentIndex.Value); + } + else + { + Value.currentAnimation = defaultAnimation.Value; + } + } + + protected override void WriteDelta(BinaryWriter writer) + { + NetString currentAnimationName = new NetString(Value.currentAnimationName); + currentAnimationName.Write(writer); + + + NetInt currentAnimationListIndex = new NetInt(Value.currentAnimationListIndex); + currentAnimationListIndex.Write(writer); + + NetTexture2DExtended texture = new NetTexture2DExtended(Value.getExtendedTexture()); + texture.Write(writer); + + NetAnimation defaultDrawFrame = new NetAnimation(Value.defaultDrawFrame); + defaultDrawFrame.Write(writer); + + NetBool enabled = new NetBool(Value.enabled); + enabled.Write(writer); + + NetString animationData = new NetString(Value.animationDataString); + animationData.Write(writer); + + } + } +} diff --git a/GeneralMods/StardustCore/NetCode/ModdedClient.cs b/GeneralMods/StardustCore/NetCode/ModdedClient.cs new file mode 100644 index 00000000..5ede46b4 --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/ModdedClient.cs @@ -0,0 +1,158 @@ +using System; +using System.IO; +using Lidgren.Network; +using StardewValley; +using StardewValley.Network; + +namespace StardustCore.NetCode +{ + public class ModdedClient : Client + { + private string address; + private NetClient client; + private bool serverDiscovered; + + public ModdedClient(string address) + { + this.address = address; + } + + public override string getUserID() + { + return ""; + } + + protected override string getHostUserName() + { + return this.client.ServerConnection.RemoteEndPoint.Address.ToString(); + } + + protected override void connectImpl() + { + NetPeerConfiguration config = new NetPeerConfiguration("StardewValley"); + config.EnableMessageType(NetIncomingMessageType.DiscoveryResponse); + config.ConnectionTimeout = 30f; + config.PingInterval = 5f; + config.MaximumTransmissionUnit = 1200; + this.client = new NetClient(config); + this.client.Start(); + int serverPort = 24642; + if (this.address.Contains(":")) + { + string[] strArray = this.address.Split(':'); + this.address = strArray[0]; + serverPort = Convert.ToInt32(strArray[1]); + } + this.client.DiscoverKnownPeer(this.address, serverPort); + } + + public override void disconnect(bool neatly = true) + { + if (this.client.ConnectionStatus != NetConnectionStatus.Disconnected && this.client.ConnectionStatus != NetConnectionStatus.Disconnecting) + { + if (neatly) + this.sendMessage(new OutgoingMessage((byte)19, Game1.player, new object[0])); + this.client.FlushSendQueue(); + this.client.Disconnect(""); + this.client.FlushSendQueue(); + } + this.connectionMessage = (string)null; + } + + protected virtual bool validateProtocol(string version) + { + return version ==ModCore.multiplayer.protocolVersion; + } + + protected override void receiveMessagesImpl() + { + NetIncomingMessage netIncomingMessage; + while ((netIncomingMessage = this.client.ReadMessage()) != null) + { + switch (netIncomingMessage.MessageType) + { + case NetIncomingMessageType.StatusChanged: + this.statusChanged(netIncomingMessage); + continue; + case NetIncomingMessageType.Data: + this.parseDataMessageFromServer(netIncomingMessage); + continue; + case NetIncomingMessageType.DiscoveryResponse: + Console.WriteLine("Found server at " + (object)netIncomingMessage.SenderEndPoint); + if (this.validateProtocol(netIncomingMessage.ReadString())) + { + this.serverName = netIncomingMessage.ReadString(); + this.receiveHandshake(netIncomingMessage); + this.serverDiscovered = true; + continue; + } + this.connectionMessage = "Strings\\UI:CoopMenu_FailedProtocolVersion"; + this.client.Disconnect(""); + continue; + case NetIncomingMessageType.DebugMessage: + case NetIncomingMessageType.WarningMessage: + case NetIncomingMessageType.ErrorMessage: + string str = netIncomingMessage.ReadString(); + Console.WriteLine("{0}: {1}", (object)netIncomingMessage.MessageType, (object)str); + Game1.debugOutput = str; + continue; + default: + continue; + } + } + if (this.client.ServerConnection == null || DateTime.Now.Second % 2 != 0) + return; + Game1.debugOutput = "Ping: " + (object)(float)((double)this.client.ServerConnection.AverageRoundtripTime * 1000.0) + "ms"; + } + + private void receiveHandshake(NetIncomingMessage msg) + { + this.client.Connect(msg.SenderEndPoint.Address.ToString(), msg.SenderEndPoint.Port); + } + + private void statusChanged(NetIncomingMessage message) + { + switch ((NetConnectionStatus)message.ReadByte()) + { + case NetConnectionStatus.Disconnecting: + case NetConnectionStatus.Disconnected: + this.clientRemotelyDisconnected(); + break; + } + } + + private void clientRemotelyDisconnected() + { + this.timedOut = true; + } + + public override void sendMessage(OutgoingMessage message) + { + NetOutgoingMessage message1 = this.client.CreateMessage(); + using (NetBufferWriteStream bufferWriteStream = new NetBufferWriteStream((NetBuffer)message1)) + { + using (BinaryWriter writer = new BinaryWriter((Stream)bufferWriteStream)) + message.Write(writer); + } + int num = (int)this.client.SendMessage(message1, NetDeliveryMethod.ReliableOrdered); + } + + private void parseDataMessageFromServer(NetIncomingMessage dataMsg) + { + using (IncomingMessage message = new IncomingMessage()) + { + using (NetBufferReadStream bufferReadStream = new NetBufferReadStream((NetBuffer)dataMsg)) + { + using (BinaryReader reader = new BinaryReader((Stream)bufferReadStream)) + { + while ((long)dataMsg.LengthBits - dataMsg.Position >= 8L) + { + message.Read(reader); + this.processIncomingMessage(message); + } + } + } + } + } + } +} diff --git a/GeneralMods/StardustCore/NetCode/ModdedGameServer.cs b/GeneralMods/StardustCore/NetCode/ModdedGameServer.cs new file mode 100644 index 00000000..039e426d --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/ModdedGameServer.cs @@ -0,0 +1,427 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml.Serialization; +using Microsoft.Xna.Framework; +using Netcode; +using StardewValley; +using StardewValley.Buildings; +using StardewValley.Locations; +using StardewValley.Minigames; +using StardewValley.Network; + +namespace StardustCore.NetCode +{ + public class GameServer : IGameServer + { + public List servers = new List(); + public List pendingGameAvailableActions = new List(); + + public GameServer() + { + this.servers.Add(ModCore.multiplayer.InitServer((Server)new LidgrenServer((IGameServer)this))); + if (Program.sdk.Networking == null) + return; + this.servers.Add(Program.sdk.Networking.CreateServer((IGameServer)this)); + } + + public int connectionsCount + { + get + { + return this.servers.Sum((Func)(s => s.connectionsCount)); + } + } + + public string getInviteCode() + { + foreach (Server server in this.servers) + { + string inviteCode = server.getInviteCode(); + if (inviteCode != null) + return inviteCode; + } + return (string)null; + } + + public string getUserName(long farmerId) + { + foreach (Server server in this.servers) + { + if (server.getUserName(farmerId) != null) + return server.getUserName(farmerId); + } + return (string)null; + } + + protected void initialize() + { + foreach (Server server in this.servers) + server.initialize(); + this.updateLobbyData(); + } + + public void setPrivacy(ServerPrivacy privacy) + { + foreach (Server server in this.servers) + server.setPrivacy(privacy); + } + + public void stopServer() + { + foreach (Server server in this.servers) + server.stopServer(); + } + + public void receiveMessages() + { + foreach (Server server in this.servers) + { + if (server == null) + { + ModCore.ModMonitor.Log("ERROR"); + continue; + } + server.receiveMessages(); + } + if (!this.isGameAvailable()) + return; + foreach (Action gameAvailableAction in this.pendingGameAvailableActions) + gameAvailableAction(); + this.pendingGameAvailableActions.Clear(); + } + + public void sendMessage(long peerId, OutgoingMessage message) + { + foreach (Server server in this.servers) + server.sendMessage(peerId, message); + } + + public bool canAcceptIPConnections() + { + return this.servers.Select((Func)(s => s.canAcceptIPConnections())).Aggregate(false, (Func)((a, b) => a | b)); + } + + public bool canOfferInvite() + { + return this.servers.Select((Func)(s => s.canOfferInvite())).Aggregate(false, (Func)((a, b) => a | b)); + } + + public void offerInvite() + { + foreach (Server server in this.servers) + { + if (server.canOfferInvite()) + server.offerInvite(); + } + } + + public bool connected() + { + foreach (Server server in this.servers) + { + if (!server.connected()) + return false; + } + return true; + } + + public void sendMessage(long peerId, byte messageType, Farmer sourceFarmer, params object[] data) + { + this.sendMessage(peerId, new OutgoingMessage(messageType, sourceFarmer, data)); + } + + public void sendMessages() + { + foreach (Farmer farmer in (IEnumerable)Game1.otherFarmers.Values) + { + foreach (OutgoingMessage message in (IEnumerable)farmer.messageQueue) + this.sendMessage(farmer.UniqueMultiplayerID, message); + farmer.messageQueue.Clear(); + } + } + + public void startServer() + { + Console.WriteLine("Starting server. Protocol version: " + ModCore.multiplayer.protocolVersion); + this.initialize(); + if ((NetFieldBase>)Game1.serverHost == (NetRef)null) + Game1.serverHost = new NetFarmerRoot(); + Game1.serverHost.Value = Game1.player; + Game1.serverHost.MarkClean(); + Game1.serverHost.Clock.InterpolationTicks = ModCore.multiplayer.defaultInterpolationTicks; + if ((NetFieldBase>)Game1.netWorldState == (NetRef)null) + Game1.netWorldState = new NetRoot((IWorldState)new NetWorldState()); + Game1.netWorldState.Clock.InterpolationTicks = 0; + Game1.netWorldState.Value.UpdateFromGame1(); + } + + public void sendServerIntroduction(long peer) + { + this.sendLocation(peer, (GameLocation)Game1.getFarm()); + this.sendLocation(peer, Game1.getLocationFromName("FarmHouse")); + ModCore.SerializationManager.cleanUpInventory(); + ModCore.SerializationManager.cleanUpWorld(); + ModCore.SerializationManager.cleanUpStorageContainers(); + this.sendMessage(peer, new OutgoingMessage((byte)1, Game1.serverHost.Value, new object[3] + { + (object)ModCore.multiplayer.writeObjectFullBytes((NetRoot)Game1.serverHost, new long?(peer)), + (object)ModCore.multiplayer.writeObjectFullBytes(Game1.player.teamRoot, new long?(peer)), + (object)ModCore.multiplayer.writeObjectFullBytes(Game1.netWorldState, new long?(peer)) + })); + foreach (KeyValuePair> root in Game1.otherFarmers.Roots) + { + if (root.Key != Game1.player.UniqueMultiplayerID && root.Key != peer) + this.sendMessage(peer, new OutgoingMessage((byte)2, root.Value.Value, new object[2] + { + (object)this.getUserName(root.Value.Value.UniqueMultiplayerID), + (object)ModCore.multiplayer.writeObjectFullBytes(root.Value, new long?(peer)) + })); + } + ModCore.SerializationManager.restoreAllModObjects(ModCore.SerializationManager.trackedObjectList); + } + + public void playerDisconnected(long disconnectee) + { + Farmer sourceFarmer = (Farmer)null; + Game1.otherFarmers.TryGetValue(disconnectee, out sourceFarmer); + ModCore.multiplayer.playerDisconnected(disconnectee); + if (sourceFarmer == null) + return; + OutgoingMessage message = new OutgoingMessage((byte)19, sourceFarmer, new object[0]); + foreach (long key in (IEnumerable)Game1.otherFarmers.Keys) + { + if (key != disconnectee) + this.sendMessage(key, message); + } + } + + public bool isGameAvailable() + { + /* + bool flag1 = Game1.currentMinigame is Intro || Game1.Date.DayOfMonth == 0; + bool flag2 = Game1.CurrentEvent != null && Game1.CurrentEvent.isWedding; + bool flag3 = Game1.newDaySync != null && !Game1.newDaySync.hasFinished(); + //bool flag4 = Game1.player.team.buildingLock.IsLocked(); + if (!Game1.isFestival() && !flag2 && (!flag1 && !flag3)) + return !flag4; + return false; + * + */ + return true; + } + + public bool whenGameAvailable(Action action) + { + if (this.isGameAvailable()) + { + action(); + return true; + } + this.pendingGameAvailableActions.Add(action); + return false; + } + + private void rejectFarmhandRequest(string userID, NetFarmerRoot farmer, Action sendMessage) + { + this.sendAvailableFarmhands(userID, sendMessage); + Console.WriteLine("Rejected request for farmhand " + (farmer.Value != null ? farmer.Value.UniqueMultiplayerID.ToString() : "???")); + } + + private IEnumerable cabins() + { + if (Game1.getFarm() != null) + { + foreach (Building building in Game1.getFarm().buildings) + { + if ((int)((NetFieldBase)building.daysOfConstructionLeft) <= 0 && building.indoors.Value is Cabin) + yield return building.indoors.Value as Cabin; + } + } + } + + private bool authCheck(string userID, Farmer farmhand) + { + if (!Game1.options.enableFarmhandCreation && !(bool)((NetFieldBase)farmhand.isCustomized)) + return false; + if (!(userID == "") && !(farmhand.userID.Value == "")) + return farmhand.userID.Value == userID; + return true; + } + + private Cabin findCabin(Farmer farmhand) + { + foreach (Cabin cabin in this.cabins()) + { + if (cabin.getFarmhand().Value.UniqueMultiplayerID == farmhand.UniqueMultiplayerID) + return cabin; + } + return (Cabin)null; + } + + private Farmer findOriginalFarmhand(Farmer farmhand) + { + return this.findCabin(farmhand)?.getFarmhand().Value; + } + + public void checkFarmhandRequest(string userID, NetFarmerRoot farmer, Action sendMessage, Action approve) + { + if (farmer.Value == null) + { + this.rejectFarmhandRequest(userID, farmer, sendMessage); + } + else + { + long id = farmer.Value.UniqueMultiplayerID; + if (this.whenGameAvailable((Action)(() => + { + Farmer originalFarmhand = this.findOriginalFarmhand(farmer.Value); + if (originalFarmhand == null) + { + Console.WriteLine("Rejected request for farmhand " + (object)id + ": doesn't exist"); + this.rejectFarmhandRequest(userID, farmer, sendMessage); + } + else if (!this.authCheck(userID, originalFarmhand)) + { + Console.WriteLine("Rejected request for farmhand " + (object)id + ": authorization failure"); + this.rejectFarmhandRequest(userID, farmer, sendMessage); + } + else if (Game1.otherFarmers.ContainsKey(id) && !ModCore.multiplayer.isDisconnecting(id) || Game1.serverHost.Value.UniqueMultiplayerID == id) + { + Console.WriteLine("Rejected request for farmhand " + (object)id + ": already in use"); + this.rejectFarmhandRequest(userID, farmer, sendMessage); + } + else if (this.findCabin(farmer.Value).isInventoryOpen()) + { + Console.WriteLine("Rejected request for farmhand " + (object)id + ": inventory in use"); + this.rejectFarmhandRequest(userID, farmer, sendMessage); + } + else + { + Console.WriteLine("Approved request for farmhand " + (object)id); + approve(); + ModCore.multiplayer.addPlayer(farmer); + ModCore.multiplayer.broadcastPlayerIntroduction(farmer); + this.sendServerIntroduction(id); + this.updateLobbyData(); + } + }))) + return; + Console.WriteLine("Postponing request for farmhand " + (object)id); + sendMessage(new OutgoingMessage((byte)11, Game1.player, new object[1] + { + (object)"Strings\\UI:Client_WaitForHostAvailability" + })); + } + } + + public void sendAvailableFarmhands(string userID, Action sendMessage) + { + List> netRefList = new List>(); + Game1.getFarm(); + foreach (Cabin cabin in this.cabins()) + { + NetRef farmhand = cabin.getFarmhand(); + if ((!farmhand.Value.isActive() || ModCore.multiplayer.isDisconnecting(farmhand.Value.UniqueMultiplayerID)) && (this.authCheck(userID, farmhand.Value) && !cabin.isInventoryOpen())) + netRefList.Add(farmhand); + } + using (MemoryStream memoryStream = new MemoryStream()) + { + using (BinaryWriter writer = new BinaryWriter((Stream)memoryStream)) + { + writer.Write(Game1.year); + writer.Write(Utility.getSeasonNumber(Game1.currentSeason)); + writer.Write(Game1.dayOfMonth); + writer.Write((byte)netRefList.Count); + foreach (NetRef netRef in netRefList) + { + try + { + netRef.Serializer = SaveGame.farmerSerializer; + netRef.WriteFull(writer); + } + finally + { + netRef.Serializer = (XmlSerializer)null; + } + } + memoryStream.Seek(0L, SeekOrigin.Begin); + sendMessage(new OutgoingMessage((byte)9, Game1.player, new object[1] + { + (object)memoryStream.ToArray() + })); + } + } + } + + private void sendLocation(long peer, GameLocation location) + { + this.sendMessage(peer, (byte)3, Game1.serverHost.Value, (object)ModCore.multiplayer.writeObjectFullBytes(ModCore.multiplayer.locationRoot(location), new long?(peer))); + } + + private void warpFarmer(Farmer farmer, short x, short y, string name, bool isStructure) + { + GameLocation locationFromName = Game1.getLocationFromName(name, isStructure); + locationFromName.hostSetup(); + farmer.currentLocation = locationFromName; + farmer.Position = new Vector2((float)((int)x * 64), (float)((int)y * 64 - (farmer.Sprite.getHeight() - 32) + 16)); + this.sendLocation(farmer.UniqueMultiplayerID, locationFromName); + } + + public void processIncomingMessage(IncomingMessage message) + { + switch (message.MessageType) + { + case 2: + message.Reader.ReadString(); + ModCore.multiplayer.processIncomingMessage(message); + break; + case 5: + this.warpFarmer(message.SourceFarmer, message.Reader.ReadInt16(), message.Reader.ReadInt16(), message.Reader.ReadString(), message.Reader.ReadByte() == (byte)1); + break; + default: + ModCore.multiplayer.processIncomingMessage(message); + break; + } + if (!ModCore.multiplayer.isClientBroadcastType(message.MessageType)) + return; + this.rebroadcastClientMessage(message); + } + + private void rebroadcastClientMessage(IncomingMessage message) + { + OutgoingMessage message1 = new OutgoingMessage(message); + foreach (long key in (IEnumerable)Game1.otherFarmers.Keys) + { + if (key != message.FarmerID) + this.sendMessage(key, message1); + } + } + + private void setLobbyData(string key, string value) + { + foreach (Server server in this.servers) + server.setLobbyData(key, value); + } + + private bool unclaimedFarmhandsExist() + { + foreach (Cabin cabin in this.cabins()) + { + if (cabin.farmhand.Value == null || cabin.farmhand.Value.userID.Value == "") + return true; + } + return false; + } + + public void updateLobbyData() + { + this.setLobbyData("farmName", Game1.player.farmName.Value); + this.setLobbyData("farmType", Convert.ToString(Game1.whichFarm)); + this.setLobbyData("date", Convert.ToString(new WorldDate(Game1.year, Game1.currentSeason, Game1.dayOfMonth).TotalDays)); + this.setLobbyData("farmhands", string.Join(",", Game1.getAllFarmhands().Select((Func)(farmhand => farmhand.userID.Value)).Where((Func)(user => user != "")))); + this.setLobbyData("newFarmhands", Convert.ToString(Game1.options.enableFarmhandCreation && this.unclaimedFarmhandsExist())); + } + } +} diff --git a/GeneralMods/StardustCore/NetCode/NetAnimation.cs b/GeneralMods/StardustCore/NetCode/NetAnimation.cs new file mode 100644 index 00000000..319fb2ba --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/NetAnimation.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Netcode; +using StardustCore.Animations; + +namespace StardustCore.NetCode +{ + public class NetAnimation : Netcode.NetField + { + + public NetRectangle sourceRect; + public NetInt frameDuration; + public NetInt frameDurationUntilNextAnimation; + + public NetAnimation() + { + + } + public NetAnimation(Animations.Animation animation) : base(animation) + { + + } + + public override void Set(Animation newValue) + { + this.value = newValue; + } + + protected override void ReadDelta(BinaryReader reader, NetVersion version) + { + sourceRect = new NetRectangle(); + sourceRect.Read(reader, version); + Value.sourceRectangle = sourceRect.Value; + + frameDuration = new NetInt(); + frameDuration.Read(reader, version); + Value.frameDuration = frameDuration.Value; + + frameDurationUntilNextAnimation = new NetInt(); + frameDurationUntilNextAnimation.Read(reader, version); + Value.frameDuration = frameDuration.Value; + } + + protected override void WriteDelta(BinaryWriter writer) + { + if (Value == null) return; + if (value.sourceRectangle == null) return; + + + sourceRect = new NetRectangle(Value.sourceRectangle); + sourceRect.Write(writer); + + frameDuration = new NetInt(Value.frameDuration); + frameDuration.Write(writer); + + frameDurationUntilNextAnimation = new NetInt(Value.frameCountUntilNextAnimation); + frameDurationUntilNextAnimation.Write(writer); + } + } +} diff --git a/GeneralMods/StardustCore/NetCode/NetAnimationManager.cs b/GeneralMods/StardustCore/NetCode/NetAnimationManager.cs new file mode 100644 index 00000000..68abfd62 --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/NetAnimationManager.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Netcode; +using StardewValley; +using StardewValley.Network; +using StardustCore.Animations; + +namespace StardustCore.NetCode +{ + public class NetAnimationManager : Netcode.NetField + { + + public NetAnimationManager() + { + + } + + public NetAnimationManager(Animations.AnimationManager manager): base(manager) + { + this.Set(manager); + } + + public NetString currentAnimationName; + public NetInt currentAnimationListIndex; + public NetTexture2DExtended objectTexture; + public NetAnimation defaultDrawFrame; + public NetBool enabled; + public NetString animationDataString; + + protected override void ReadDelta(BinaryReader reader, NetVersion version) + { + //Checks to see if the current animation is nothing, aka null. + NetBool isNull = new NetBool(); + isNull.Read(reader, version); + bool valueIsNull = isNull.Value; + if (isNull) return; + + + + NetString currentAnimationName = new NetString(); + currentAnimationName.Read(reader, version); + + NetInt currentIndex = new NetInt(); + currentIndex.Read(reader, version); + + NetTexture2DExtended text = new NetTexture2DExtended(); + text.Read(reader, version); + + NetAnimation defaultAnimation = new NetAnimation(); + defaultAnimation.Read(reader, version); + + NetBool enabled = new NetBool(); + enabled.Read(reader, version); + + NetString data = new NetString(); + data.Read(reader, version); + + Value.setExtendedTexture(text.Value); + Value.defaultDrawFrame = defaultAnimation.Value; + Value.enabled = enabled.Value; + //Try and prevent unnecessary parsing. + if (Value.animations == null && !String.IsNullOrEmpty(Value.animationDataString)) + { + Value.animations = Animations.AnimationManager.parseAnimationsFromXNB(data.Value); + } + if (!String.IsNullOrEmpty(data.Value)) + { + Value.setAnimation(currentAnimationName.Value, currentIndex.Value); + } + else + { + Value.currentAnimation = defaultDrawFrame.Value; + } + } + + protected override void WriteDelta(BinaryWriter writer) + { + if (Value == null) + { + throw new Exception("NULL ANIMATION MANAGER VALUE!!!"); + } + + if (String.IsNullOrEmpty(Value.currentAnimationName)) + { + NetBool isNull = new NetBool(true); + writer.Write(isNull); + return; + //throw new Exception("Null string value for currentAnimationName!"); + } + else + { + NetBool isNull = new NetBool(false); + writer.Write(isNull); + } + NetString curentAnimationName = new NetString(!String.IsNullOrEmpty(Value.currentAnimationName) ? Value.currentAnimationName : ""); + currentAnimationName.Write(writer); + + + NetInt currentAnimationListIndex = new NetInt(Value.currentAnimationListIndex); + currentAnimationListIndex.Write(writer); + + NetTexture2DExtended texture = new NetTexture2DExtended(Value.getExtendedTexture()); + texture.Write(writer); + + //do read/write null values here!!! + NetAnimation defaultDrawFrame = new NetAnimation(Value.defaultDrawFrame); + defaultDrawFrame.Write(writer); + + NetBool enabled = new NetBool(Value.enabled); + enabled.Write(writer); + + NetString animationData = new NetString(Value.animationDataString); + animationData.Write(writer); + + } + + public override void Set(AnimationManager newValue) + { + this.value = newValue; + } + } +} diff --git a/GeneralMods/StardustCore/NetCode/NetBufferReadStream.cs b/GeneralMods/StardustCore/NetCode/NetBufferReadStream.cs new file mode 100644 index 00000000..0b24e59a --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/NetBufferReadStream.cs @@ -0,0 +1,99 @@ +using System; +using System.IO; +using Lidgren.Network; + +namespace StardustCore.NetCode +{ + public class NetBufferReadStream : Stream + { + private long offset; + public NetBuffer Buffer; + + public NetBufferReadStream(NetBuffer buffer) + { + this.Buffer = buffer; + this.offset = buffer.Position; + } + + public override bool CanRead + { + get + { + return true; + } + } + + public override bool CanSeek + { + get + { + return true; + } + } + + public override bool CanWrite + { + get + { + return false; + } + } + + public override long Length + { + get + { + return ((long)this.Buffer.LengthBits - this.offset) / 8L; + } + } + + public override long Position + { + get + { + return (this.Buffer.Position - this.offset) / 8L; + } + set + { + this.Buffer.Position = this.offset + value * 8L; + } + } + + public override void Flush() + { + } + + public override int Read(byte[] buffer, int offset, int count) + { + this.Buffer.ReadBytes(buffer, offset, count); + return count; + } + + public override long Seek(long offset, SeekOrigin origin) + { + switch (origin) + { + case SeekOrigin.Begin: + this.Position = offset; + break; + case SeekOrigin.Current: + this.Position += offset; + break; + case SeekOrigin.End: + this.Position = this.Length + offset; + break; + } + return this.Position; + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotSupportedException(); + } + } +} diff --git a/GeneralMods/StardustCore/NetCode/NetBufferWriteStream.cs b/GeneralMods/StardustCore/NetCode/NetBufferWriteStream.cs new file mode 100644 index 00000000..e3b62d41 --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/NetBufferWriteStream.cs @@ -0,0 +1,97 @@ +using System; +using System.IO; +using Lidgren.Network; + +namespace StardustCore.NetCode +{ + public class NetBufferWriteStream : Stream + { + private int offset; + public NetBuffer Buffer; + + public NetBufferWriteStream(NetBuffer buffer) + { + this.Buffer = buffer; + this.offset = buffer.LengthBits; + } + + public override bool CanRead + { + get + { + return false; + } + } + + public override bool CanSeek + { + get + { + return true; + } + } + + public override bool CanWrite + { + get + { + return true; + } + } + + public override long Length + { + get + { + throw new NotSupportedException(); + } + } + + public override long Position + { + get + { + return (long)((this.Buffer.LengthBits - this.offset) / 8); + } + set + { + this.Buffer.LengthBits = (int)((long)this.offset + value * 8L); + } + } + + public override void Flush() + { + } + + public override int Read(byte[] buffer, int offset, int count) + { + throw new NotSupportedException(); + } + + public override long Seek(long offset, SeekOrigin origin) + { + switch (origin) + { + case SeekOrigin.Begin: + this.Position = offset; + break; + case SeekOrigin.Current: + this.Position += offset; + break; + case SeekOrigin.End: + throw new NotSupportedException(); + } + return this.Position; + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + this.Buffer.Write(buffer, offset, count); + } + } +} diff --git a/GeneralMods/StardustCore/NetCode/NetKeyValuePair.cs b/GeneralMods/StardustCore/NetCode/NetKeyValuePair.cs new file mode 100644 index 00000000..afeb5082 --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/NetKeyValuePair.cs @@ -0,0 +1,30 @@ +using Netcode; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.NetCode +{ + public class NetKeyValuePair : NetField, NetKeyValuePair> where KField : NetField, new() where VField : NetField, new() + { + public override void Set(KeyValuePair newValue) + { + this.value = newValue; + } + + protected override void ReadDelta(BinaryReader reader, NetVersion version) + { + throw new NotImplementedException(); + } + + protected override void WriteDelta(BinaryWriter writer) + { + throw new NotImplementedException(); + } + + + } +} diff --git a/GeneralMods/StardustCore/NetCode/NetPairs/NetVector2MultiTilePair.cs b/GeneralMods/StardustCore/NetCode/NetPairs/NetVector2MultiTilePair.cs new file mode 100644 index 00000000..f719de5e --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/NetPairs/NetVector2MultiTilePair.cs @@ -0,0 +1,36 @@ +using Microsoft.Xna.Framework; +using Netcode; +using StardustCore.Objects; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.NetCode.NetPairs +{ + public class NetVector2MultiTilePair: NetKeyValuePair + { + + public NetVector2MultiTilePair() + { + + } + + public NetVector2MultiTilePair(KeyValuePair hello) + { + this.Set(Value); + } + + public override void Read(BinaryReader reader, NetVersion version) + { + base.Read(reader, version); + } + + public override void Write(BinaryWriter writer) + { + base.Write(writer); + } + } +} diff --git a/GeneralMods/StardustCore/NetCode/NetTexure2DExtended.cs b/GeneralMods/StardustCore/NetCode/NetTexure2DExtended.cs new file mode 100644 index 00000000..a70a204f --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/NetTexure2DExtended.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Netcode; +using StardewValley; +using StardustCore.UIUtilities; + +namespace StardustCore.NetCode +{ + public class NetTexture2DExtended : Netcode.NetField + { + + + + public NetTexture2DExtended() + { + + } + + public NetTexture2DExtended(Texture2DExtended value) : base(value) + { + } + + public void ReadData(BinaryReader reader, NetVersion version) + { + ReadDelta(reader, version); + } + + public override void Set(Texture2DExtended newValue) + { + this.value = newValue; + } + + public void WriteData(BinaryWriter writer) + { + WriteDelta(writer); + } + + protected override void ReadDelta(BinaryReader reader, NetVersion version) + { + NetString name = new NetString(); + name.Read(reader, version); + + NetString iD = new NetString(); + iD.Read(reader, version); + + + StardustCore.ModCore.ModMonitor.Log("Name: "+name); + StardustCore.ModCore.ModMonitor.Log("Mod ID:"+iD); + + + //Texture2D texture = new Texture2D(Game1.graphics.GraphicsDevice,width,height); + if (String.IsNullOrEmpty(iD.Value) || String.IsNullOrEmpty(name.Value)) return; + + + Texture2DExtended texture = ModCore.TextureManagers[iD.Value].getTexture(name.Value); + this.Value = texture; + + } + + protected override void WriteDelta(BinaryWriter writer) + { + NetString name = new NetString(Value.Name); + name.Write(writer); + + NetString iD = new NetString(Value.modID); + iD.Write(writer); + + } + + + } +} diff --git a/GeneralMods/StardustCore/NetCode/Objects/NetCoreObject.cs b/GeneralMods/StardustCore/NetCode/Objects/NetCoreObject.cs new file mode 100644 index 00000000..1a4d9273 --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/Objects/NetCoreObject.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization.Formatters.Binary; +using System.Text; +using System.Threading.Tasks; +using Netcode; +using StardewValley; +using StardustCore.NetCode.Graphics; +using StardustCore.UIUtilities; + +namespace StardustCore.NetCode +{ + public class NetCoreObject : Netcode.NetField + { + + + public NetInt which; + public NetVector2 tilePos; + + + public NetRectangle boundingBox; + + + + public NetVector2 position; + public NetInt Decoration_type; + public NetInt rotations; + public NetInt currentRotation; + public NetInt sourceIndexOffset; + public NetVector2 drawPosition; + public NetRectangle sourceRect; + public NetRectangle defaultSourceRect; + public NetRectangle defaultBoundingBox; + public NetString description; + public NetTexture2DExtended texture; + public NetBool flipped; + public NetBool flaggedForPickup; + public NetBool lightGlowAdded; + public NetObjectList inventory; + public NetInt InventoryMaxSize; + public NetBool itemReadyForHarvest; + public NetBool lightsOn; + public NetString locationName; + public NetColor lightColor; + public NetBool removable; + public NetColor drawColor; + public NetBool useXML; + public NetString serializationName; + + //Animation Manager..... + public NetAnimationManager animationManager; + + + + + public NetCoreObject() + { + + } + + public NetCoreObject(CoreObject value) : base(value) + { + Set(value); + } + + public override void Set(CoreObject newValue) + { + this.value = newValue; + } + + protected override void ReadDelta(BinaryReader reader, NetVersion version) + { + texture = new NetTexture2DExtended(); + texture.Read(reader, version); + Value.setExtendedTexture(texture.Value); + + which = new NetInt(); + which.Read(reader, version); + Value.ParentSheetIndex = which.Value; + + tilePos = new NetVector2(); + tilePos.Read(reader, version); + Value.TileLocation = tilePos.Value; + + InventoryMaxSize = new NetInt(); + InventoryMaxSize.Read(reader, version); + Value.inventoryMaxSize = InventoryMaxSize.Value; + + sourceRect = new NetRectangle(); + sourceRect.Read(reader, version); + Value.sourceRect = sourceRect.Value; + + boundingBox = new NetRectangle(); + boundingBox.Read(reader, version); + Value.boundingBox.Value = boundingBox.Value; + + drawPosition = new NetVector2(); + drawPosition.Read(reader, version); + Value.drawPosition = drawPosition.Value; + + animationManager = new NetAnimationManager(); + animationManager.Read(reader, version); + Value.animationManager = animationManager.Value; + } + + protected override void WriteDelta(BinaryWriter writer) + { + texture = new NetTexture2DExtended(Value.getExtendedTexture()); + texture.Write(writer); + + which = new NetInt(Value.ParentSheetIndex); + which.Write(writer); + + tilePos = new NetVector2(Value.TileLocation); + tilePos.Write(writer); + + InventoryMaxSize = new NetInt(Value.inventoryMaxSize); + InventoryMaxSize.Write(writer); + + sourceRect = new NetRectangle(Value.sourceRect); + sourceRect.Write(writer); + + boundingBox = new NetRectangle(Value.boundingBox.Value); + sourceRect.Write(writer); + + drawPosition = new NetVector2(Value.drawPosition); + drawPosition.Write(writer); + + + animationManager = new NetAnimationManager(Value.animationManager); + animationManager.Write(writer); + + } + } +} \ No newline at end of file diff --git a/GeneralMods/StardustCore/NetCode/Objects/NetMultiTileComponent.cs b/GeneralMods/StardustCore/NetCode/Objects/NetMultiTileComponent.cs new file mode 100644 index 00000000..11dbfe7a --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/Objects/NetMultiTileComponent.cs @@ -0,0 +1,116 @@ +using Netcode; +using StardustCore.NetCode.Graphics; +using StardustCore.Objects; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.NetCode.Objects +{ + public class NetMultiTileComponent : Netcode.NetField + { + private NetTexture2DExtended texture; + private NetInt which; + private NetVector2 tilePos; + private NetRectangle sourceRect; + private NetRectangle boundingBox; + private NetVector2 drawPosition; + private NetAnimationManager animationManager; + + public NetMultiTileComponent() + { + + } + + public NetMultiTileComponent(MultiTileComponent obj): base(obj) + { + + } + + public NetInt InventoryMaxSize { get; private set; } + + public override void Set(MultiTileComponent newValue) + { + this.value = newValue; + } + + protected override void ReadDelta(BinaryReader reader, NetVersion version) + { + + texture = new NetTexture2DExtended(); + texture.Read(reader, version); + + which = new NetInt(); + which.Read(reader, version); + Value.ParentSheetIndex = which.Value; + + tilePos = new NetVector2(); + tilePos.Read(reader, version); + Value.TileLocation = tilePos.Value; + + InventoryMaxSize = new NetInt(); + InventoryMaxSize.Read(reader, version); + Value.inventoryMaxSize = InventoryMaxSize.Value; + + sourceRect = new NetRectangle(); + sourceRect.Read(reader, version); + Value.sourceRect = sourceRect.Value; + + boundingBox = new NetRectangle(); + boundingBox.Read(reader, version); + Value.boundingBox.Value = boundingBox.Value; + + drawPosition = new NetVector2(); + drawPosition.Read(reader, version); + Value.drawPosition = drawPosition.Value; + + animationManager = new NetAnimationManager(); + animationManager.Read(reader, version); + Value.animationManager = animationManager.Value; + //NetCoreObject obj = new NetCoreObject(); + //obj.ReadData(reader, version); + + /* + NetMultiTileObject hmm = new NetMultiTileObject(); + hmm.Read(reader,version); + Value.containerObject = hmm.Value; + */ + } + + protected override void WriteDelta(BinaryWriter writer) + { + //NetCoreObject obj = new NetCoreObject(Value); + //obj.WriteData(writer); + + texture = new NetTexture2DExtended(Value.getExtendedTexture()); + texture.Write(writer); + + which = new NetInt(Value.ParentSheetIndex); + which.Write(writer); + + tilePos = new NetVector2(Value.TileLocation); + tilePos.Write(writer); + + InventoryMaxSize = new NetInt(Value.inventoryMaxSize); + InventoryMaxSize.Write(writer); + + sourceRect = new NetRectangle(Value.sourceRect); + sourceRect.Write(writer); + + boundingBox = new NetRectangle(Value.boundingBox.Value); + sourceRect.Write(writer); + + drawPosition = new NetVector2(Value.drawPosition); + drawPosition.Write(writer); + + animationManager = new NetAnimationManager(Value.animationManager); + animationManager.Write(writer); + + //NetMultiTileObject hmm = new NetMultiTileObject(Value.containerObject); + //hmm.Write(writer); + } + } +} diff --git a/GeneralMods/StardustCore/NetCode/Objects/NetMultiTileObject.cs b/GeneralMods/StardustCore/NetCode/Objects/NetMultiTileObject.cs new file mode 100644 index 00000000..3136d8bb --- /dev/null +++ b/GeneralMods/StardustCore/NetCode/Objects/NetMultiTileObject.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework; +using Netcode; +using StardustCore.Objects; + +namespace StardustCore.NetCode.Objects +{ + public class NetMultiTileObject : Netcode.NetField + { + public NetMultiTileObject() + { + + } + + public NetMultiTileObject(MultiTileObject obj): base(obj) + { + + } + + public override void Set(MultiTileObject newValue) + { + this.value = newValue; + } + + protected override void ReadDelta(BinaryReader reader, NetVersion version) + { + NetCoreObject obj = new NetCoreObject(); + obj.Read(reader, version); + //Values already taken care of in NetCoreObject + + NetList, NetKeyValuePair> netList = new NetList, NetKeyValuePair>(); + netList.Read(reader, version); + Value.objects = netList.ToList(); + + NetColor col = new NetColor(); + col.Read(reader, version); + Value.categoryColor = col.Value; + + NetString name = new NetString(); + name.Read(reader, version); + Value.categoryName = name.Value; + } + + protected override void WriteDelta(BinaryWriter writer) + { + NetCoreObject obj = new NetCoreObject(Value); + obj.Write(writer); + + NetList, NetKeyValuePair> netList = new NetList, NetKeyValuePair>(); + foreach (var v in Value.objects) + { + netList.Add(v); + } + netList.Write(writer); + + NetColor col = new NetColor(Value.categoryColor); + col.Write(writer); + + NetString catName = new NetString(Value.categoryName); + catName.Write(writer); + } + } +} diff --git a/GeneralMods/StardustCore/Objects/CoreObject.cs b/GeneralMods/StardustCore/Objects/CoreObject.cs index 0de68f0e..fe141896 100644 --- a/GeneralMods/StardustCore/Objects/CoreObject.cs +++ b/GeneralMods/StardustCore/Objects/CoreObject.cs @@ -13,7 +13,6 @@ using StardustCore.UIUtilities; using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Xml.Serialization; namespace StardustCore @@ -105,6 +104,7 @@ namespace StardustCore lightColor = Color.Black; base.initNetFields(); + this.NetFields.AddField(new NetCode.NetCoreObject(this)); } @@ -113,6 +113,7 @@ namespace StardustCore { base.initNetFields(); this.updateDrawPosition(); + this.NetFields.AddField(new NetCode.NetCoreObject(this)); } @@ -120,6 +121,7 @@ namespace StardustCore { base.initNetFields(); //does nothng + this.NetFields.AddField(new NetCode.NetCoreObject(this)); } @@ -709,14 +711,17 @@ namespace StardustCore foreach (Farmer farmer in Game1.getAllFarmers()) { - if (farmer.currentLocation != location) continue; - if (farmer.GetBoundingBox().Intersects(this.boundingBox.Value)) + if (location == farmer.currentLocation) { - Game1.showRedMessage("Can't place on top of a person."); - bool result = false; - return result; + if (farmer.GetBoundingBox().Intersects(this.boundingBox.Value)) + { + Game1.showRedMessage("Can't place on top of a person."); + bool result = false; + return result; + } } } + this.updateDrawPosition(); bool f = Utilities.placementAction(this, location, x, y, StardustCore.ModCore.SerializationManager,who); diff --git a/GeneralMods/StardustCore/Objects/MultiTileComponent.cs b/GeneralMods/StardustCore/Objects/MultiTileComponent.cs index 9ef847a0..bf3610cb 100644 --- a/GeneralMods/StardustCore/Objects/MultiTileComponent.cs +++ b/GeneralMods/StardustCore/Objects/MultiTileComponent.cs @@ -18,6 +18,7 @@ namespace StardustCore.Objects public MultiTileComponent() { //this.TextureSheet = new Texture2DExtended(); + this.NetFields.AddField(new NetCode.NetTexture2DExtended(this.getExtendedTexture())); } public MultiTileComponent(CoreObject part) @@ -32,6 +33,10 @@ namespace StardustCore.Objects this.defaultBoundingBox = new Rectangle(0, 0, 16, 16); this.boundingBox.Value = new Rectangle((int)0 * Game1.tileSize, (int)0* Game1.tileSize, 1 * Game1.tileSize, 1 * Game1.tileSize); + + //this.NetFields.AddField(new NetCode.NetTexture2DExtended(this.getExtendedTexture())); + + this.InitializeBasics(0, Vector2.Zero); } public MultiTileComponent(int which,String name, String description, Texture2DExtended texture) @@ -49,6 +54,11 @@ namespace StardustCore.Objects this.serializationName = this.GetType().ToString(); this.ParentSheetIndex = which; + this.animationManager = new Animations.AnimationManager(texture, new Animations.Animation(this.defaultSourceRect), false); + + //this.NetFields.AddField(new NetCode.NetTexture2DExtended(this.getExtendedTexture())); + + this.InitializeBasics(0, Vector2.Zero); } public MultiTileComponent(int which,String name, String description, Animations.AnimationManager animationManager) @@ -66,6 +76,23 @@ namespace StardustCore.Objects this.defaultSourceRect = this.sourceRect; this.serializationName = this.GetType().ToString(); this.ParentSheetIndex = which; + + //this.NetFields.AddField(new NetCode.NetTexture2DExtended(this.getExtendedTexture())); + + this.InitializeBasics(0,Vector2.Zero); + } + + public override void InitializeBasics(int InvMaxSize, Vector2 tile) + { + this.inventory = new List(); + this.inventoryMaxSize = InvMaxSize; + this.TileLocation = tile; + lightsOn = false; + + lightColor = Color.Black; + + base.initNetFields(); + this.NetFields.AddField(new NetCode.Objects.NetMultiTileComponent(this)); } public override bool clicked(Farmer who) @@ -102,16 +129,21 @@ namespace StardustCore.Objects this.position = new Vector2(point.X, point.Y); this.TileLocation = new Vector2((float)point.X, (float)point.Y); this.boundingBox.Value = new Rectangle((int)TileLocation.X * Game1.tileSize, (int)TileLocation.Y * Game1.tileSize, 1 * Game1.tileSize, 1 * Game1.tileSize); - foreach (Farmer farmer in Game1.getAllFarmers()) + + foreach(Farmer farmer in Game1.getAllFarmers()) { - if (farmer.currentLocation != location) continue; - if (farmer.GetBoundingBox().Intersects(this.boundingBox.Value)) + if (location == farmer.currentLocation) { - Game1.showRedMessage("Can't place on top of a person."); - bool result = false; - return result; + if (farmer.GetBoundingBox().Intersects(this.boundingBox.Value)) + { + Game1.showRedMessage("Can't place on top of a person."); + bool result = false; + return result; + } } } + + this.updateDrawPosition(); bool f = Utilities.placementAction(this, location, x, y,StardustCore.ModCore.SerializationManager ,who); diff --git a/GeneralMods/StardustCore/Objects/MultiTileObject.cs b/GeneralMods/StardustCore/Objects/MultiTileObject.cs index 2700b10c..67a2b806 100644 --- a/GeneralMods/StardustCore/Objects/MultiTileObject.cs +++ b/GeneralMods/StardustCore/Objects/MultiTileObject.cs @@ -32,7 +32,7 @@ namespace StardustCore.Objects this.name = Name; this.displayName = Name; this.description = Description; - + this.animationManager = new Animations.AnimationManager(this.TextureSheet, new Animations.Animation(), false); foreach(var v in this.objects) { v.Value.containerObject = this; @@ -81,7 +81,15 @@ namespace StardustCore.Objects public override void InitializeBasics(int InvMaxSize, Vector2 tile) { - base.InitializeBasics(InvMaxSize, tile); + this.inventory = new List(); + this.inventoryMaxSize = InvMaxSize; + this.TileLocation = tile; + lightsOn = false; + + lightColor = Color.Black; + + base.initNetFields(); + this.NetFields.AddField(new NetCode.Objects.NetMultiTileObject(this)); } public override bool placementAction(GameLocation location, int x, int y, Farmer who = null) { diff --git a/GeneralMods/StardustCore/StardustCore.csproj b/GeneralMods/StardustCore/StardustCore.csproj index df097d9d..09216db5 100644 --- a/GeneralMods/StardustCore/StardustCore.csproj +++ b/GeneralMods/StardustCore/StardustCore.csproj @@ -95,6 +95,20 @@ + + + + + + + + + + + + + +