diff --git a/GeneralMods/BuyBackCollectables/Framework/BuyBackMenu.cs b/GeneralMods/BuyBackCollectables/Framework/BuyBackMenu.cs
index 717ddc84..92e6b3e6 100644
--- a/GeneralMods/BuyBackCollectables/Framework/BuyBackMenu.cs
+++ b/GeneralMods/BuyBackCollectables/Framework/BuyBackMenu.cs
@@ -224,6 +224,7 @@ namespace Omegasis.BuyBackCollectables.Framework
if (current2.containsPoint(x, y) && this.NewItem != null && Game1.player.money >= this.Value)
{
Game1.player.money -= this.Value;
+ Game1.playSound("coin");
Game1.player.addItemByMenuIfNecessary(this.NewItem);
}
}
@@ -239,6 +240,7 @@ namespace Omegasis.BuyBackCollectables.Framework
{
Game1.player.money -= this.Value;
Game1.player.addItemByMenuIfNecessary(this.NewItem);
+ Game1.playSound("coin");
}
}
diff --git a/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs b/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs
index 0ec7bbda..0be9151e 100644
--- a/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs
+++ b/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs
@@ -3,9 +3,15 @@ using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
using StardewValley.Menus;
+using StardewValley.Quests;
+using System;
namespace Omegasis.DailyQuestAnywhere
{
+ /*
+ *TODO: Make quest core mod???
+ */
+
/// The mod entry point.
public class DailyQuestAnywhere : Mod
{
@@ -15,6 +21,8 @@ namespace Omegasis.DailyQuestAnywhere
/// The mod configuration.
private ModConfig Config;
+ Quest dailyQuest;
+
/*********
** Public methods
@@ -26,9 +34,12 @@ namespace Omegasis.DailyQuestAnywhere
this.Config = helper.ReadConfig();
ControlEvents.KeyPressed += this.ControlEvents_KeyPressed;
+ StardewModdingAPI.Events.SaveEvents.AfterSave += SaveEvents_AfterSave;
}
+
+
/*********
** Private methods
*********/
@@ -38,7 +49,53 @@ namespace Omegasis.DailyQuestAnywhere
private void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e)
{
if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.Config.KeyBinding)
- Game1.activeClickableMenu = new Billboard(true);
+ if (Game1.player.hasDailyQuest() == false )
+ {
+ if (this.dailyQuest == null)
+ {
+ this.dailyQuest = generateDailyQuest();
+ }
+ Game1.questOfTheDay = this.dailyQuest;
+ Game1.activeClickableMenu = new Billboard(true);
+ }
+ }
+
+ ///
+ /// Makes my daily quest referene null so we can't just keep getting a new reference.
+ ///
+ ///
+ ///
+ private void SaveEvents_AfterSave(object sender, System.EventArgs e)
+ {
+ this.dailyQuest = null; //Nullify my quest reference.
+ }
+
+ ///
+ /// Generate a daily quest for sure.
+ ///
+ ///
+ public Quest generateDailyQuest()
+ {
+
+ Random chanceRandom = new Random((int)Game1.uniqueIDForThisGame + (int)Game1.stats.DaysPlayed);
+ int chance = chanceRandom.Next(0, 101);
+ float actualChance = chance / 100;
+
+ //If we hit the chance for actually generating a daily quest do so, otherwise don't generate a daily quest.
+ if (actualChance <= Config.chanceForDailyQuest)
+ {
+ Random r = new Random((int)Game1.uniqueIDForThisGame + (int)Game1.stats.DaysPlayed);
+ int rand = r.Next(0, 7);
+
+ if (rand == 0) return new ItemDeliveryQuest();
+ if (rand == 1) return new FishingQuest();
+ if (rand == 2) return new StardewValley.Quests.CraftingQuest();
+ if (rand == 3) return new StardewValley.Quests.ItemDeliveryQuest();
+ if (rand == 4) return new StardewValley.Quests.ItemHarvestQuest();
+ if (rand == 5) return new StardewValley.Quests.ResourceCollectionQuest();
+ if (rand == 6) return new StardewValley.Quests.SlayMonsterQuest();
+ }
+ return null; //This should never happen.
}
}
}
diff --git a/GeneralMods/DailyQuestAnywhere/Framework/ModConfig.cs b/GeneralMods/DailyQuestAnywhere/Framework/ModConfig.cs
index 8f1a2f0c..a6f01664 100644
--- a/GeneralMods/DailyQuestAnywhere/Framework/ModConfig.cs
+++ b/GeneralMods/DailyQuestAnywhere/Framework/ModConfig.cs
@@ -5,5 +5,10 @@
{
/// The key which shows the menu.
public string KeyBinding { get; set; } = "H";
+
+ ///
+ /// The chance for a daily quest to actually happen.
+ ///
+ public float chanceForDailyQuest { get; set; } = .75f;
}
}
diff --git a/GeneralMods/Fall28SnowDay/manifest.json b/GeneralMods/Fall28SnowDay/manifest.json
index cd1457ca..be64d502 100644
--- a/GeneralMods/Fall28SnowDay/manifest.json
+++ b/GeneralMods/Fall28SnowDay/manifest.json
@@ -1,7 +1,7 @@
{
"Name": "Fall 28 Snow Day",
"Author": "Alpha_Omegasis",
- "Version": "1.4.1",
+ "Version": "1.5.0",
"Description": "Makes it snow on Fall 28, which makes a good explanation for all the snow on the next day.",
"UniqueID": "Omegasis.Fall28SnowDay",
"EntryDll": "Fall28SnowDay.dll",
diff --git a/GeneralMods/HappyBirthday/Framework/Messages.cs b/GeneralMods/HappyBirthday/Framework/Messages.cs
index 8d2c1c04..3f702845 100644
--- a/GeneralMods/HappyBirthday/Framework/Messages.cs
+++ b/GeneralMods/HappyBirthday/Framework/Messages.cs
@@ -1,4 +1,5 @@
using StardewValley;
+using System.Collections.Generic;
namespace Omegasis.HappyBirthday.Framework
{
@@ -12,7 +13,12 @@ namespace Omegasis.HappyBirthday.Framework
/// The message to display.
public static void ShowStarMessage(string message)
{
+ //IEnumerable players= Game1.getAllFarmers();
+
Game1.addHUDMessage(new HUDMessage(message, 1));
+
+
+
if (!message.Contains("Inventory"))
{
Game1.playSound("cancel");
diff --git a/GeneralMods/HappyBirthday/HappyBirthday.cs b/GeneralMods/HappyBirthday/HappyBirthday.cs
index 6acd46ff..95092bb6 100644
--- a/GeneralMods/HappyBirthday/HappyBirthday.cs
+++ b/GeneralMods/HappyBirthday/HappyBirthday.cs
@@ -59,12 +59,12 @@ namespace Omegasis.HappyBirthday
{
["Robin"] = "Hey @, happy birthday! I'm glad you choose this town to move here to. ",
["Demetrius"] = "Happy birthday @! Make sure you take some time off today to enjoy yourself. $h",
- ["Maru"] = "Happy birthday @. I tried to make you an everlasting candle but sadly that didn't work out. Maybe next year right? $h",
+ ["Maru"] = "Happy birthday @. I tried to make you an everlasting candle for you, but sadly that didn't work out. Maybe next year right? $h",
["Sebastian"] = "Happy birthday @. Here's to another year of chilling. ",
["Linus"] = "Happy birthday @. Thanks for visiting me even on your birthday. It makes me really happy. ",
["Pierre"] = "Hey @, happy birthday! Hopefully this next year for you will be a great one! ",
["Caroline"] = "Happy birthday @. Thank you for all that you've done for our community. I'm sure your parents must be proud of you.$h",
- ["Abigail"] = "Happy Birthday @! Hopefully this year we can go on even more adventures together $h!",
+ ["Abigail"] = "Happy birthday @! Hopefully this year we can go on even more adventures together $h!",
["Alex"] = "Yo @, happy birthday! Maybe this will be your best year yet.$h",
["George"] = "When you get to my age birthdays come and go. Still happy birthday @.",
["Evelyn"] = "Happy birthday @. You have grown up to be such a fine individual and I'm sure you'll continue to grow. ",
diff --git a/GeneralMods/ModdedUtilitiesNetworking/Class1.cs b/GeneralMods/ModdedUtilitiesNetworking/Class1.cs
new file mode 100644
index 00000000..15a2edf9
--- /dev/null
+++ b/GeneralMods/ModdedUtilitiesNetworking/Class1.cs
@@ -0,0 +1,195 @@
+using Galaxy.Api;
+using ModdedUtilitiesNetworking.Framework;
+using ModdedUtilitiesNetworking.Framework.Clients;
+using ModdedUtilitiesNetworking.Framework.Delegates;
+using ModdedUtilitiesNetworking.Framework.Extentions;
+using ModdedUtilitiesNetworking.Framework.Servers;
+using StardewModdingAPI;
+using StardewValley;
+using StardewValley.Network;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Text;
+using System.Threading.Tasks;
+using static ModdedUtilitiesNetworking.Framework.Delegates.DelegateInfo;
+
+namespace ModdedUtilitiesNetworking
+{
+ public class ModCore : Mod
+ {
+ public static CustomMultiplayer multiplayer;
+
+ public static IModHelper helper;
+ public static IMonitor monitor;
+ public static IManifest manifest;
+ bool multiplayerSet;
+
+ public static Dictionary objectTypes = new Dictionary();
+ public static Dictionary possibleVoidFunctions = new Dictionary();
+
+ public static string displayMessageString = "Omegasis.ModdedUtilitiesNetworking.ModCore.displayMessage";
+
+ public override void Entry(IModHelper helper)
+ {
+ helper = Helper;
+ monitor = Monitor;
+ manifest = ModManifest;
+
+ StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_AfterLoad;
+ StardewModdingAPI.Events.ControlEvents.KeyPressed += ControlEvents_KeyPressed;
+ multiplayerSet = false;
+ multiplayer = new CustomMultiplayer();
+
+ possibleVoidFunctions.Add(displayMessageString, new voidFunc(displayMessage));
+ initializeBasicTypes();
+
+ }
+
+
+ private void ControlEvents_KeyPressed(object sender, StardewModdingAPI.Events.EventArgsKeyPressed e)
+ {
+
+ if (e.KeyPressed==Microsoft.Xna.Framework.Input.Keys.K)
+ {
+ multiplayer.sendModInfoReturnVoid(displayMessageString, typeof(String), (object)"My love is like fire.");
+ }
+ }
+
+ ///
+ /// Don't change this. Sets appropriate clients and servers once the game has loaded.
+ ///
+ ///
+ ///
+ private void SaveEvents_AfterLoad(object sender, EventArgs e)
+ {
+ if (Game1.server != null && multiplayerSet == false)
+ {
+ List servers = new List();
+ if (Game1.server != null)
+ {
+ ModCore.monitor.Log(Game1.server.GetType().ToString());
+ //var property = ModCore.helper.Reflection.GetProperty>(Game1.server, "servers", true);
+
+ Type type = Game1.server.GetType();
+ BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
+
+ // get the field info
+ FieldInfo finfo = type.GetField("servers", bindingFlags);
+
+
+ var list = (List)finfo.GetValue(Game1.server);
+
+ foreach (var server in list)
+ {
+ servers.Add(server);
+ }
+ }
+ Game1.server.stopServer();
+ Game1.server = new CustomGameServer();
+ multiplayerSet = true;
+
+ (Game1.server as CustomGameServer).startServer();
+
+ ModCore.monitor.Log("Custom multiplayer binding success!");
+ }
+
+ if(Game1.client !=null && multiplayerSet == false)
+ {
+ if(Game1.client is LidgrenClient)
+ {
+
+ BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
+
+ // get the field info
+ FieldInfo finfo = typeof(LidgrenClient).GetField("address", bindingFlags);
+
+
+ var address = (string)finfo.GetValue(Game1.client);
+
+ Game1.client.disconnect(true); //Disconnect old client
+ CustomLidgrenClient client = new CustomLidgrenClient(address);
+ Game1.client = client;
+ client.connect(); //Connect new client.
+ multiplayerSet = true;
+
+ }
+ if(Game1.client is StardewValley.SDKs.GalaxyNetClient)
+ {
+ BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
+
+ // get the field info
+ FieldInfo finfo = typeof(StardewValley.SDKs.GalaxyNetClient).GetField("lobbyId", bindingFlags);
+
+
+ var galaxyID = (GalaxyID)finfo.GetValue(Game1.client);
+
+ Game1.client.disconnect(true); //Disconnect old client
+ CustomGalaxyClient client = new CustomGalaxyClient(galaxyID);
+ Game1.client = client;
+ client.connect(); //Connect new client.
+ multiplayerSet = true;
+ }
+ }
+ }
+
+ ///
+ /// Static Debug function.
+ ///
+ ///
+ public static void displayMessage(object param)
+ {
+ string s =(string) param;
+ monitor.Log(s);
+ }
+
+ ///
+ /// Initialize basic supported types.
+ ///
+ public static void initializeBasicTypes()
+ {
+
+ objectTypes.Add(typeof(String).ToString(), new ReadWriter(new reader(BinaryReadWriteExtentions.ReadString), new writer(BinaryReadWriteExtentions.WriteString)));
+
+ }
+
+ ///
+ /// Process all possible functions that can occur.
+ ///
+ ///
+ ///
+ public static void processVoidFunction(string key,object obj)
+ {
+ foreach(var v in possibleVoidFunctions)
+ {
+ if (v.Key == key) v.Value.Invoke(obj);
+ }
+ }
+
+ ///
+ /// Process all possible data types.
+ ///
+ ///
+ ///
+ ///
+ public static object processTypes(BinaryReader msg,string key)
+ {
+ foreach(var v in objectTypes)
+ {
+ if (v.Key == key)
+ {
+ object o= v.Value.read(msg);
+ return o;
+ }
+ }
+ monitor.Log("Error: type not found: " + key, LogLevel.Error);
+ return null;
+ }
+
+ }
+
+
+}
diff --git a/GeneralMods/ModdedUtilitiesNetworking/Framework/Clients/CustomGalaxyClient.cs b/GeneralMods/ModdedUtilitiesNetworking/Framework/Clients/CustomGalaxyClient.cs
new file mode 100644
index 00000000..ab820906
--- /dev/null
+++ b/GeneralMods/ModdedUtilitiesNetworking/Framework/Clients/CustomGalaxyClient.cs
@@ -0,0 +1,151 @@
+using Galaxy.Api;
+using StardewValley;
+using StardewValley.Network;
+using StardewValley.SDKs;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ModdedUtilitiesNetworking.Framework.Clients
+{
+ class CustomGalaxyClient :GalaxyNetClient
+ {
+ private GalaxyID lobbyId;
+ private GalaxySocket client;
+ private GalaxyID serverId;
+
+ public CustomGalaxyClient(GalaxyID lobbyId) : base(lobbyId)
+ {
+ this.lobbyId = lobbyId;
+ }
+
+ public override string getUserID()
+ {
+ return Convert.ToString(GalaxyInstance.User().GetGalaxyID().ToUint64());
+ }
+
+ protected override string getHostUserName()
+ {
+ return GalaxyInstance.Friends().GetFriendPersonaName(this.serverId);
+ }
+
+ protected override void connectImpl()
+ {
+ this.client = new GalaxySocket(ModCore.multiplayer.protocolVersion);
+ GalaxyInstance.User().GetGalaxyID();
+ this.client.JoinLobby(this.lobbyId);
+ ModCore.monitor.Log("Success on generating modded galaxy client.");
+ }
+
+ public override void disconnect(bool neatly = true)
+ {
+ if (this.client == null)
+ return;
+ Console.WriteLine("Disconnecting from server {0}", (object)this.lobbyId);
+ this.client.Close();
+ this.client = (GalaxySocket)null;
+ this.connectionMessage = (string)null;
+ }
+
+ protected override void receiveMessagesImpl()
+ {
+ if (this.client == null || !this.client.Connected)
+ return;
+ if (this.client.Connected && this.serverId == (GalaxyID)null)
+ this.serverId = this.client.LobbyOwner;
+ this.client.Receive(new Action(this.onReceiveConnection), new Action(this.onReceiveMessage), new Action(this.onReceiveDisconnect), new Action(this.onReceiveError));
+ this.client.Heartbeat(Enumerable.Repeat(this.serverId, 1));
+ if (this.client.GetTimeSinceLastMessage(this.serverId) <= 30000L)
+ return;
+ this.timedOut = true;
+ this.disconnect(true);
+ }
+
+ private void onReceiveConnection(GalaxyID peer)
+ {
+ }
+
+ private void onReceiveMessage(GalaxyID peer, Stream messageStream)
+ {
+ if (peer != this.serverId)
+ return;
+ using (IncomingMessage message = new IncomingMessage())
+ {
+ using (BinaryReader reader = new BinaryReader(messageStream))
+ {
+ message.Read(reader);
+ this.processIncomingMessage(message);
+ }
+ }
+ }
+
+ private void onReceiveDisconnect(GalaxyID peer)
+ {
+ if (peer != this.serverId)
+ ModCore.multiplayer.playerDisconnected((long)peer.ToUint64());
+ else
+ this.timedOut = true;
+ }
+
+ private void onReceiveError(string messageKey)
+ {
+ this.connectionMessage = messageKey;
+ }
+
+ public override void sendMessage(OutgoingMessage message)
+ {
+ if (this.client == null || !this.client.Connected || this.serverId == (GalaxyID)null)
+ return;
+ this.client.Send(this.serverId, message);
+ }
+
+ protected override void processIncomingMessage(IncomingMessage message)
+ {
+ byte messageType = message.MessageType;
+ if ((uint)messageType <= 9U)
+ {
+ switch (messageType)
+ {
+ case 1:
+ this.receiveServerIntroduction(message.Reader);
+ return;
+ case 2:
+ this.userNames[message.FarmerID] = message.Reader.ReadString();
+ ModCore.multiplayer.processIncomingMessage(message);
+ return;
+ case 3:
+ ModCore.multiplayer.processIncomingMessage(message);
+ return;
+ case 9:
+ this.receiveAvailableFarmhands(message.Reader);
+ return;
+ }
+ }
+ else if ((int)messageType != 11)
+ {
+ if ((int)messageType == 16)
+ {
+ if (message.FarmerID != Game1.serverHost.Value.UniqueMultiplayerID)
+ return;
+ this.receiveUserNameUpdate(message.Reader);
+ return;
+ }
+ }
+ else
+ {
+ this.connectionMessage = message.Reader.ReadString();
+ return;
+ }
+
+ if (message.MessageType == 20)
+ {
+ ModCore.monitor.Log("JUMPING JELLYBEANS!!!");
+ }
+
+ ModCore.multiplayer.processIncomingMessage(message); //If we don't know how to initially process the message, send it to the multiplayer function.
+ }
+ }
+}
diff --git a/GeneralMods/ModdedUtilitiesNetworking/Framework/Clients/CustomLidgrenClient.cs b/GeneralMods/ModdedUtilitiesNetworking/Framework/Clients/CustomLidgrenClient.cs
new file mode 100644
index 00000000..24560034
--- /dev/null
+++ b/GeneralMods/ModdedUtilitiesNetworking/Framework/Clients/CustomLidgrenClient.cs
@@ -0,0 +1,211 @@
+using Lidgren.Network;
+using ModdedUtilitiesNetworking.Framework.Network;
+using StardewValley;
+using StardewValley.Network;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Netcode;
+using ModdedUtilitiesNetworking.Framework.Extentions;
+
+namespace ModdedUtilitiesNetworking.Framework.Clients
+{
+ class CustomLidgrenClient : LidgrenClient
+ {
+ private string address;
+ private NetClient client;
+ private bool serverDiscovered;
+
+ public CustomLidgrenClient(string address) : base(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.EnableMessageType(NetIncomingMessageType.Data);
+ 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);
+ ModCore.monitor.Log("Success on generating modded lidgren client.");
+ }
+
+ 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.ErrorMessage:
+ case NetIncomingMessageType.DebugMessage:
+ case NetIncomingMessageType.WarningMessage:
+ string str = netIncomingMessage.ReadString();
+ Console.WriteLine("{0}: {1}", (object)netIncomingMessage.MessageType, (object)str);
+ Game1.debugOutput = str;
+ continue;
+ case NetIncomingMessageType.StatusChanged:
+ this.statusChanged(netIncomingMessage);
+ continue;
+ case NetIncomingMessageType.Data:
+ this.parseDataMessageFromServer(netIncomingMessage);
+ continue;
+ case NetIncomingMessageType.DiscoveryResponse:
+ ModCore.monitor.Log("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;
+ 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.Disconnected:
+ case NetConnectionStatus.Disconnecting:
+ 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);
+ }
+ }
+ }
+ }
+ }
+
+ protected override void processIncomingMessage(IncomingMessage message)
+ {
+ base.processIncomingMessage(message);
+
+ //Packet signiture for functions that return nothing.
+ if (message.MessageType == 20)
+ {
+
+ object[] obj = message.Reader.ReadModdedInfoPacket();
+ string functionName = (string)obj[0];
+ string classType = (string)obj[1];
+ object actualObject = ModCore.processTypes(message.Reader, classType);
+ ModCore.processVoidFunction(functionName, actualObject);
+ return;
+ }
+
+
+
+ //message.Reader.ReadChar();
+ //Write Binary ententions reader
+
+ //ModCore.multiplayer.processIncomingMessage(message); //If we don't know how to initially process the message, send it to the multiplayer function.
+ }
+
+ protected override void receiveServerIntroduction(BinaryReader msg)
+ {
+ Game1.otherFarmers.Roots[Game1.player.UniqueMultiplayerID] = (NetRoot)(Game1.player.NetFields.Root as NetFarmerRoot);
+ NetFarmerRoot netFarmerRoot = ModCore.multiplayer.readFarmer(msg);
+ long uniqueMultiplayerId = netFarmerRoot.Value.UniqueMultiplayerID;
+ Game1.serverHost = netFarmerRoot;
+ Game1.serverHost.Value.teamRoot = ModCore.multiplayer.readObjectFull(msg);
+ Game1.otherFarmers.Roots.Remove(uniqueMultiplayerId);
+ Game1.otherFarmers.Roots.Add(uniqueMultiplayerId, (NetRoot)netFarmerRoot);
+ Game1.player.teamRoot = Game1.serverHost.Value.teamRoot;
+ Game1.netWorldState = ModCore.multiplayer.readObjectFull(msg);
+ Game1.netWorldState.Clock.InterpolationTicks = 0;
+ Game1.netWorldState.Value.WriteToGame1();
+ this.setUpGame();
+ if (Game1.chatBox == null)
+ return;
+ Game1.chatBox.listPlayers();
+ }
+ }
+}
diff --git a/GeneralMods/ModdedUtilitiesNetworking/Framework/CustomMultiplayer.cs b/GeneralMods/ModdedUtilitiesNetworking/Framework/CustomMultiplayer.cs
new file mode 100644
index 00000000..9ffd0c8c
--- /dev/null
+++ b/GeneralMods/ModdedUtilitiesNetworking/Framework/CustomMultiplayer.cs
@@ -0,0 +1,108 @@
+using ModdedUtilitiesNetworking.Framework.Messages;
+using ModdedUtilitiesNetworking.Framework.Servers;
+using StardewValley;
+using StardewValley.Network;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Text;
+using System.Threading.Tasks;
+using static ModdedUtilitiesNetworking.Framework.Delegates.DelegateInfo;
+
+namespace ModdedUtilitiesNetworking.Framework
+{
+ public class CustomMultiplayer : StardewValley.Multiplayer
+ {
+
+ public override bool isClientBroadcastType(byte messageType)
+ {
+ return true;
+ }
+
+ ///
+ /// Sends an outgoing message to appropriate players.
+ ///
+ ///
+ public void sendMessage(OutgoingMessage message)
+ {
+ if (Game1.server != null)
+ {
+ foreach (long peerId in (IEnumerable)Game1.otherFarmers.Keys)
+ {
+ Game1.server.sendMessage(peerId, message);
+ }
+ }
+ if (Game1.client != null)
+ {
+ Game1.client.sendMessage(message);
+ }
+ }
+
+
+ ///
+ /// Updates the server.
+ ///
+ public override void UpdateEarly()
+ {
+ if (Game1.CurrentEvent == null)
+ this.removeDisconnectedFarmers();
+ this.updatePendingConnections();
+ if (Game1.server != null)
+ (Game1.server as CustomGameServer).receiveMessages();
+ else if (Game1.client != null)
+ Game1.client.receiveMessages();
+ this.tickFarmerRoots();
+ this.tickLocationRoots();
+ }
+
+ ///
+ /// Creates a net outgoing message that is written specifically to call a void function when sent.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public OutgoingMessage sendOutGoingMessageReturnVoid(string functionName, string objectParametersType, object data, Farmer source)
+ {
+ OutgoingMessage message = new OutgoingMessage((byte)20, source, makeDataArray(functionName, objectParametersType, data));
+ return message;
+ }
+
+ public OutgoingMessage sendOutGoingMessageReturnVoid(string functionName, Type objectParametersType, object data, Farmer source)
+ {
+ OutgoingMessage message = new OutgoingMessage((byte)20, source, makeDataArray(functionName, objectParametersType.ToString(), data));
+ return message;
+ }
+
+
+ public object[] makeDataArray(string functionName, string objectParametersType, object data)
+ {
+ object[] obj = new object[3]
+ {
+ functionName,
+ objectParametersType,
+ data
+ };
+ return obj;
+ }
+
+ ///
+ /// Creates all of the necessary parameters for the outgoing message to be sent to the server/client on what to do and how to handle the data sent.
+ /// This message written will attempt to access a function that doesn't return anything. Essentially null.
+ ///
+ ///
+ ///
+ ///
+ public void sendModInfoReturnVoid(string uniqueID,Type classType,object data)
+ {
+ Farmer f = Game1.player;
+
+ OutgoingMessage message =ModCore.multiplayer.sendOutGoingMessageReturnVoid(uniqueID, classType, data, f);
+
+ ModCore.multiplayer.sendMessage(message);
+ }
+
+ }
+}
diff --git a/GeneralMods/ModdedUtilitiesNetworking/Framework/Delegates/DelegateInfo.cs b/GeneralMods/ModdedUtilitiesNetworking/Framework/Delegates/DelegateInfo.cs
new file mode 100644
index 00000000..fc1f5ba7
--- /dev/null
+++ b/GeneralMods/ModdedUtilitiesNetworking/Framework/Delegates/DelegateInfo.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using static ModdedUtilitiesNetworking.Framework.Delegates.DelegateInfo;
+
+namespace ModdedUtilitiesNetworking.Framework.Delegates
+{
+
+ public class DelegateInfo
+ {
+ public delegate void voidFunc(object obj);
+
+ public delegate object reader(BinaryReader reader);
+ public delegate void writer(BinaryWriter writer, object obj);
+
+
+ }
+
+
+ public class ReadWriter
+ {
+ reader reader;
+ writer writer;
+ public ReadWriter(reader reader, writer writer)
+ {
+ this.reader = reader;
+ this.writer = writer;
+ }
+
+ public void write(BinaryWriter bWriter, object obj)
+ {
+ writer.Invoke(bWriter, obj);
+ }
+
+ public object read(BinaryReader bReader)
+ {
+ return reader.Invoke(bReader);
+ }
+
+ }
+}
diff --git a/GeneralMods/ModdedUtilitiesNetworking/Framework/Extentions/BinaryReadWriteExtentions.cs b/GeneralMods/ModdedUtilitiesNetworking/Framework/Extentions/BinaryReadWriteExtentions.cs
new file mode 100644
index 00000000..fb76d085
--- /dev/null
+++ b/GeneralMods/ModdedUtilitiesNetworking/Framework/Extentions/BinaryReadWriteExtentions.cs
@@ -0,0 +1,65 @@
+using Microsoft.Xna.Framework;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Netcode;
+namespace ModdedUtilitiesNetworking.Framework.Extentions
+{
+ public static class BinaryReadWriteExtentions
+ {
+ public static Vector3 ReadVector3(this BinaryReader reader)
+ {
+ float x=reader.ReadSingle();
+ float y=reader.ReadSingle();
+ float z=reader.ReadSingle();
+ return new Vector3(x, y, z);
+ }
+
+ public static string ReadString(this BinaryReader reader)
+ {
+ String s= reader.ReadString();
+ return new string(s.ToCharArray());
+ }
+
+ public static void WriteString(this BinaryWriter writer, object str)
+ {
+ writer.WriteString((string)str);
+ }
+
+ ///
+ /// Read the custom info packet sent from a modded client or server.
+ ///
+ ///
+ ///
+ public static object[] ReadModdedInfoPacket(this BinaryReader reader)
+ {
+ object[] o = new object[2]
+ {
+ reader.ReadString(),
+ reader.ReadString()
+ };
+ return o;
+ }
+
+ ///
+ /// Read the remaining byte data in an array.
+ ///
+ ///
+ ///
+ public static byte[] ReadAllBytes(this BinaryReader reader)
+ {
+ using (var memoryStream = new MemoryStream())
+ {
+ reader.BaseStream.CopyTo(memoryStream);
+
+ return memoryStream.ToArray();
+ }
+ }
+
+ //Can do custom classes here for reading and writing.
+ //That way it will be better to save/load data
+ }
+}
diff --git a/GeneralMods/ModdedUtilitiesNetworking/Framework/Messages/OutgoingMessageBase.cs b/GeneralMods/ModdedUtilitiesNetworking/Framework/Messages/OutgoingMessageBase.cs
new file mode 100644
index 00000000..47093365
--- /dev/null
+++ b/GeneralMods/ModdedUtilitiesNetworking/Framework/Messages/OutgoingMessageBase.cs
@@ -0,0 +1,142 @@
+using Microsoft.Xna.Framework;
+using Netcode;
+using StardewValley;
+using StardewValley.Network;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ModdedUtilitiesNetworking.Framework.Messages
+{
+ public class OutgoingMessageBase
+ {
+
+ public byte messageType;
+ public long farmerID;
+ public object[] data;
+ public string uniqueID;
+
+ public byte MessageType
+ {
+ get
+ {
+ return this.messageType;
+ }
+ }
+
+ public long FarmerID
+ {
+ get
+ {
+ return this.farmerID;
+ }
+ }
+
+ public Farmer SourceFarmer
+ {
+ get
+ {
+ return Game1.getFarmer(this.farmerID);
+ }
+ }
+
+ public string UniqueID{
+ get
+ {
+ return this.uniqueID;
+ }
+ }
+
+ public ReadOnlyCollection