Slowly updating mods. Managed to create mod that syncs mod data between clients and server.
This commit is contained in:
parent
ccddf1d423
commit
b5a7d9797c
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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???
|
||||
*/
|
||||
|
||||
/// <summary>The mod entry point.</summary>
|
||||
public class DailyQuestAnywhere : Mod
|
||||
{
|
||||
|
@ -15,6 +21,8 @@ namespace Omegasis.DailyQuestAnywhere
|
|||
/// <summary>The mod configuration.</summary>
|
||||
private ModConfig Config;
|
||||
|
||||
Quest dailyQuest;
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
|
@ -26,9 +34,12 @@ namespace Omegasis.DailyQuestAnywhere
|
|||
this.Config = helper.ReadConfig<ModConfig>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes my daily quest referene null so we can't just keep getting a new reference.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void SaveEvents_AfterSave(object sender, System.EventArgs e)
|
||||
{
|
||||
this.dailyQuest = null; //Nullify my quest reference.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a daily quest for sure.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,5 +5,10 @@
|
|||
{
|
||||
/// <summary>The key which shows the menu.</summary>
|
||||
public string KeyBinding { get; set; } = "H";
|
||||
|
||||
/// <summary>
|
||||
/// The chance for a daily quest to actually happen.
|
||||
/// </summary>
|
||||
public float chanceForDailyQuest { get; set; } = .75f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using StardewValley;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Omegasis.HappyBirthday.Framework
|
||||
{
|
||||
|
@ -12,7 +13,12 @@ namespace Omegasis.HappyBirthday.Framework
|
|||
/// <param name="message">The message to display.</param>
|
||||
public static void ShowStarMessage(string message)
|
||||
{
|
||||
//IEnumerable<Farmer> players= Game1.getAllFarmers();
|
||||
|
||||
Game1.addHUDMessage(new HUDMessage(message, 1));
|
||||
|
||||
|
||||
|
||||
if (!message.Contains("Inventory"))
|
||||
{
|
||||
Game1.playSound("cancel");
|
||||
|
|
|
@ -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. ",
|
||||
|
|
|
@ -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<string, ReadWriter> objectTypes = new Dictionary<string, ReadWriter>();
|
||||
public static Dictionary<string, voidFunc> possibleVoidFunctions = new Dictionary<string, voidFunc>();
|
||||
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Don't change this. Sets appropriate clients and servers once the game has loaded.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void SaveEvents_AfterLoad(object sender, EventArgs e)
|
||||
{
|
||||
if (Game1.server != null && multiplayerSet == false)
|
||||
{
|
||||
List<Server> servers = new List<Server>();
|
||||
if (Game1.server != null)
|
||||
{
|
||||
ModCore.monitor.Log(Game1.server.GetType().ToString());
|
||||
//var property = ModCore.helper.Reflection.GetProperty<List<Server>>(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<Server>)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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Static Debug function.
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
public static void displayMessage(object param)
|
||||
{
|
||||
string s =(string) param;
|
||||
monitor.Log(s);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize basic supported types.
|
||||
/// </summary>
|
||||
public static void initializeBasicTypes()
|
||||
{
|
||||
|
||||
objectTypes.Add(typeof(String).ToString(), new ReadWriter(new reader(BinaryReadWriteExtentions.ReadString), new writer(BinaryReadWriteExtentions.WriteString)));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process all possible functions that can occur.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="obj"></param>
|
||||
public static void processVoidFunction(string key,object obj)
|
||||
{
|
||||
foreach(var v in possibleVoidFunctions)
|
||||
{
|
||||
if (v.Key == key) v.Value.Invoke(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process all possible data types.
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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<GalaxyID>(this.onReceiveConnection), new Action<GalaxyID, Stream>(this.onReceiveMessage), new Action<GalaxyID>(this.onReceiveDisconnect), new Action<string>(this.onReceiveError));
|
||||
this.client.Heartbeat(Enumerable.Repeat<GalaxyID>(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.
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Farmer>)(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<FarmerTeam>(msg);
|
||||
Game1.otherFarmers.Roots.Remove(uniqueMultiplayerId);
|
||||
Game1.otherFarmers.Roots.Add(uniqueMultiplayerId, (NetRoot<Farmer>)netFarmerRoot);
|
||||
Game1.player.teamRoot = Game1.serverHost.Value.teamRoot;
|
||||
Game1.netWorldState = ModCore.multiplayer.readObjectFull<IWorldState>(msg);
|
||||
Game1.netWorldState.Clock.InterpolationTicks = 0;
|
||||
Game1.netWorldState.Value.WriteToGame1();
|
||||
this.setUpGame();
|
||||
if (Game1.chatBox == null)
|
||||
return;
|
||||
Game1.chatBox.listPlayers();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends an outgoing message to appropriate players.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
public void sendMessage(OutgoingMessage message)
|
||||
{
|
||||
if (Game1.server != null)
|
||||
{
|
||||
foreach (long peerId in (IEnumerable<long>)Game1.otherFarmers.Keys)
|
||||
{
|
||||
Game1.server.sendMessage(peerId, message);
|
||||
}
|
||||
}
|
||||
if (Game1.client != null)
|
||||
{
|
||||
Game1.client.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Updates the server.
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a net outgoing message that is written specifically to call a void function when sent.
|
||||
/// </summary>
|
||||
/// <param name="functionName"></param>
|
||||
/// <param name="objectParametersType"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="uniqueID"></param>
|
||||
/// <param name="classType"></param>
|
||||
/// <param name="data"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read the custom info packet sent from a modded client or server.
|
||||
/// </summary>
|
||||
/// <param name="reader"></param>
|
||||
/// <returns></returns>
|
||||
public static object[] ReadModdedInfoPacket(this BinaryReader reader)
|
||||
{
|
||||
object[] o = new object[2]
|
||||
{
|
||||
reader.ReadString(),
|
||||
reader.ReadString()
|
||||
};
|
||||
return o;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read the remaining byte data in an array.
|
||||
/// </summary>
|
||||
/// <param name="reader"></param>
|
||||
/// <returns></returns>
|
||||
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
|
||||
}
|
||||
}
|
|
@ -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<object> Data
|
||||
{
|
||||
get
|
||||
{
|
||||
return Array.AsReadOnly<object>(this.data);
|
||||
}
|
||||
}
|
||||
|
||||
public OutgoingMessageBase(byte messageType, long farmerID, string uniqueID, params object[] data)
|
||||
{
|
||||
this.messageType = messageType;
|
||||
this.farmerID = farmerID;
|
||||
this.uniqueID = uniqueID;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public virtual OutgoingMessageBase generateOutgoingMessage(byte messageType, Farmer sourceFarmer, string uniqueID ,params object[] data)
|
||||
{
|
||||
return new OutgoingMessageBase(messageType, sourceFarmer.UniqueMultiplayerID, uniqueID ,data);
|
||||
}
|
||||
|
||||
/*
|
||||
public virtual OutgoingMessageBase generateOutgoingMessage(IncomingMessage message)
|
||||
{
|
||||
OutgoingMessageBase msg = new OutgoingMessageBase(message.MessageType, message.FarmerID, message.uniqueID,new object[1]
|
||||
{
|
||||
(object) message.Data
|
||||
});
|
||||
return msg;
|
||||
}
|
||||
*/
|
||||
|
||||
public virtual void Write(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(this.messageType);
|
||||
writer.Write(this.farmerID);
|
||||
writer.Write(this.uniqueID);
|
||||
object[] data = this.data;
|
||||
BinaryReaderWriterExtensions.WriteSkippable(writer, (Action)(() =>
|
||||
{
|
||||
foreach (object enumValue in data)
|
||||
{
|
||||
if (enumValue is Vector2)
|
||||
{
|
||||
writer.Write(((Vector2)enumValue).X);
|
||||
writer.Write(((Vector2)enumValue).Y);
|
||||
}
|
||||
else if (enumValue is Guid)
|
||||
writer.Write(((Guid)enumValue).ToByteArray());
|
||||
else if (enumValue is byte[])
|
||||
writer.Write((byte[])enumValue);
|
||||
else if (enumValue is bool)
|
||||
writer.Write((bool)enumValue ? (byte)1 : (byte)0);
|
||||
else if (enumValue is byte)
|
||||
writer.Write((byte)enumValue);
|
||||
else if (enumValue is int)
|
||||
writer.Write((int)enumValue);
|
||||
else if (enumValue is short)
|
||||
writer.Write((short)enumValue);
|
||||
else if (enumValue is float)
|
||||
writer.Write((float)enumValue);
|
||||
else if (enumValue is long)
|
||||
writer.Write((long)enumValue);
|
||||
else if (enumValue is string)
|
||||
writer.Write((string)enumValue);
|
||||
else if (enumValue is string[])
|
||||
{
|
||||
string[] strArray = (string[])enumValue;
|
||||
writer.Write((byte)strArray.Length);
|
||||
for (int index = 0; index < strArray.Length; ++index)
|
||||
writer.Write(strArray[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(enumValue is IConvertible) || !enumValue.GetType().IsValueType)
|
||||
throw new InvalidDataException();
|
||||
BinaryReaderWriterExtensions.WriteEnum(writer, enumValue);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public virtual OutgoingMessage convertToOutgoingMessage()
|
||||
{
|
||||
return new OutgoingMessage(this.messageType, this.farmerID, this.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ModdedUtilitiesNetworking.Framework.Network
|
||||
{
|
||||
public class NetBufferReadStream : Stream
|
||||
{
|
||||
private long offset;
|
||||
public NetBuffer Buffer;
|
||||
|
||||
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 NetBufferReadStream(NetBuffer buffer)
|
||||
{
|
||||
this.Buffer = buffer;
|
||||
this.offset = buffer.Position;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (origin == SeekOrigin.Begin)
|
||||
this.Position = offset;
|
||||
else if (origin == SeekOrigin.Current)
|
||||
this.Position = this.Position + offset;
|
||||
else if (origin == SeekOrigin.End)
|
||||
this.Position = this.Length + offset;
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ModdedUtilitiesNetworking.Framework.Network
|
||||
{
|
||||
|
||||
public class NetBufferWriteStream : Stream
|
||||
{
|
||||
private int offset;
|
||||
public NetBuffer Buffer;
|
||||
|
||||
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 NetBufferWriteStream(NetBuffer buffer)
|
||||
{
|
||||
this.Buffer = buffer;
|
||||
this.offset = buffer.LengthBits;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (origin == SeekOrigin.Begin)
|
||||
this.Position = offset;
|
||||
else if (origin == SeekOrigin.Current)
|
||||
this.Position = this.Position + offset;
|
||||
else if (origin == 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,433 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using ModdedUtilitiesNetworking.Framework.Extentions;
|
||||
using Netcode;
|
||||
using StardewValley;
|
||||
using StardewValley.Buildings;
|
||||
using StardewValley.Locations;
|
||||
using StardewValley.Minigames;
|
||||
using StardewValley.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ModdedUtilitiesNetworking.Framework.Servers
|
||||
{
|
||||
public class CustomGameServer : IGameServer
|
||||
{
|
||||
public List<Server> servers = new List<Server>();
|
||||
public List<Action> pendingGameAvailableActions = new List<Action>();
|
||||
|
||||
public CustomGameServer()
|
||||
{
|
||||
this.servers = new List<Server>();
|
||||
this.servers.Add(ModCore.multiplayer.InitServer((Server)new LidgrenServer((IGameServer)this)));
|
||||
ModCore.monitor.Log("Custom Lidgren Server Created");
|
||||
ModCore.monitor.Log("Custom Game Server Created");
|
||||
if (Program.sdk.Networking == null)
|
||||
return;
|
||||
this.servers.Add(Program.sdk.Networking.CreateServer((IGameServer)this));
|
||||
}
|
||||
|
||||
public CustomGameServer(List<Server> servers)
|
||||
{
|
||||
this.servers = new List<Server>();
|
||||
|
||||
foreach(var server in servers)
|
||||
{
|
||||
this.servers.Add(server);
|
||||
}
|
||||
}
|
||||
|
||||
public int connectionsCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return Enumerable.Sum<Server>((IEnumerable<Server>)this.servers, (Func<Server, int>)(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)
|
||||
{
|
||||
if (server.connected() == true) continue;
|
||||
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)
|
||||
{
|
||||
server.receiveMessages();
|
||||
}
|
||||
if (!this.isGameAvailable())
|
||||
return;
|
||||
foreach (Action action in this.pendingGameAvailableActions)
|
||||
action();
|
||||
this.pendingGameAvailableActions.Clear();
|
||||
}
|
||||
|
||||
public void sendMessage(long peerId, OutgoingMessage message)
|
||||
{
|
||||
foreach (Server server in this.servers)
|
||||
server.sendMessage(peerId, message);
|
||||
}
|
||||
|
||||
public bool canAcceptIPConnections()
|
||||
{
|
||||
return Enumerable.Aggregate<bool, bool>(Enumerable.Select<Server, bool>((IEnumerable<Server>)this.servers, (Func<Server, bool>)(s => s.canAcceptIPConnections())), false, (Func<bool, bool, bool>)((a, b) => a | b));
|
||||
}
|
||||
|
||||
public bool canOfferInvite()
|
||||
{
|
||||
return Enumerable.Aggregate<bool, bool>(Enumerable.Select<Server, bool>((IEnumerable<Server>)this.servers, (Func<Server, bool>)(s => s.canOfferInvite())), false, (Func<bool, bool, bool>)((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<Farmer>)Game1.otherFarmers.Values)
|
||||
{
|
||||
foreach (OutgoingMessage message in (IEnumerable<OutgoingMessage>)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<Farmer, NetRef<Farmer>>)Game1.serverHost == (NetRef<Farmer>)null)
|
||||
Game1.serverHost = new NetFarmerRoot();
|
||||
Game1.serverHost.Value = Game1.player;
|
||||
Game1.serverHost.MarkClean();
|
||||
Game1.serverHost.Clock.InterpolationTicks = ModCore.multiplayer.defaultInterpolationTicks;
|
||||
if ((NetFieldBase<IWorldState, NetRef<IWorldState>>)Game1.netWorldState == (NetRef<IWorldState>)null)
|
||||
Game1.netWorldState = new NetRoot<IWorldState>((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"));
|
||||
this.sendMessage(peer, new OutgoingMessage((byte)1, Game1.serverHost.Value, new object[3]
|
||||
{
|
||||
(object) ModCore.multiplayer.writeObjectFullBytes<Farmer>((NetRoot<Farmer>) Game1.serverHost, new long?(peer)),
|
||||
(object) ModCore.multiplayer.writeObjectFullBytes<FarmerTeam>(Game1.player.teamRoot, new long?(peer)),
|
||||
(object) ModCore.multiplayer.writeObjectFullBytes<IWorldState>(Game1.netWorldState, new long?(peer))
|
||||
}));
|
||||
foreach (KeyValuePair<long, NetRoot<Farmer>> keyValuePair in Game1.otherFarmers.Roots)
|
||||
{
|
||||
if (keyValuePair.Key != Game1.player.UniqueMultiplayerID && keyValuePair.Key != peer)
|
||||
this.sendMessage(peer, new OutgoingMessage((byte)2, keyValuePair.Value.Value, new object[2]
|
||||
{
|
||||
(object) this.getUserName(keyValuePair.Value.Value.UniqueMultiplayerID),
|
||||
(object) ModCore.multiplayer.writeObjectFullBytes<Farmer>(keyValuePair.Value, new long?(peer))
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
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 peerId in (IEnumerable<long>)Game1.otherFarmers.Keys)
|
||||
{
|
||||
if (peerId != disconnectee)
|
||||
this.sendMessage(peerId, 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();
|
||||
if (!Game1.isFestival() && !flag2 && !flag1)
|
||||
return !flag3;
|
||||
return false;
|
||||
}
|
||||
|
||||
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<OutgoingMessage> sendMessage)
|
||||
{
|
||||
this.sendAvailableFarmhands(userID, sendMessage);
|
||||
Console.WriteLine("Rejected request for farmhand " + (farmer.Value != null ? farmer.Value.UniqueMultiplayerID.ToString() : "???"));
|
||||
}
|
||||
|
||||
private IEnumerable<Cabin> cabins()
|
||||
{
|
||||
if (Game1.getFarm() != null)
|
||||
{
|
||||
foreach (Building building in Game1.getFarm().buildings)
|
||||
{
|
||||
if ((int)((NetFieldBase<int, NetInt>)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<bool, NetBool>)farmhand.isCustomized))
|
||||
return false;
|
||||
if (!(userID == "") && !(farmhand.userID.Value == ""))
|
||||
return farmhand.userID.Value == userID;
|
||||
return true;
|
||||
}
|
||||
|
||||
private Farmer findOriginalFarmhand(Farmer farmhand)
|
||||
{
|
||||
foreach (Cabin cabin in this.cabins())
|
||||
{
|
||||
if (cabin.getFarmhand().Value.UniqueMultiplayerID == farmhand.UniqueMultiplayerID)
|
||||
return cabin.getFarmhand().Value;
|
||||
}
|
||||
return (Farmer)null;
|
||||
}
|
||||
|
||||
public void checkFarmhandRequest(string userID, NetFarmerRoot farmer, Action<OutgoingMessage> 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
|
||||
{
|
||||
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<OutgoingMessage> sendMessage)
|
||||
{
|
||||
List<NetRef<Farmer>> list = new List<NetRef<Farmer>>();
|
||||
Game1.getFarm();
|
||||
foreach (Cabin cabin in this.cabins())
|
||||
{
|
||||
NetRef<Farmer> farmhand = cabin.getFarmhand();
|
||||
if ((!farmhand.Value.isActive() || ModCore.multiplayer.isDisconnecting(farmhand.Value.UniqueMultiplayerID)) && this.authCheck(userID, farmhand.Value))
|
||||
list.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)list.Count);
|
||||
foreach (NetRef<Farmer> netRef in list)
|
||||
{
|
||||
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<GameLocation>(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);
|
||||
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)
|
||||
{
|
||||
//ModCore.monitor.Log("MESSAGES????");
|
||||
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(), (int)message.Reader.ReadByte() == 1);
|
||||
break;
|
||||
case 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);
|
||||
break;
|
||||
default:
|
||||
ModCore.multiplayer.processIncomingMessage(message);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
this.rebroadcastClientMessage(message);
|
||||
}
|
||||
|
||||
private void rebroadcastClientMessage(IncomingMessage message)
|
||||
{
|
||||
OutgoingMessage message1 = new OutgoingMessage(message);
|
||||
foreach (long peerId in (IEnumerable<long>)Game1.otherFarmers.Keys)
|
||||
{
|
||||
if (peerId != message.FarmerID)
|
||||
this.sendMessage(peerId, 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(",", Enumerable.Where<string>(Enumerable.Select<Farmer, string>(Game1.getAllFarmhands(), (Func<Farmer, string>)(farmhand => farmhand.userID.Value)), (Func<string, bool>)(user => user != ""))));
|
||||
this.setLobbyData("newFarmhands", Convert.ToString(Game1.options.enableFarmhandCreation && this.unclaimedFarmhandsExist()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
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;
|
||||
|
||||
namespace ModdedUtilitiesNetworking.Framework.Servers
|
||||
{
|
||||
class CustomLidgrenServer : LidgrenServer
|
||||
{
|
||||
private HashSet<NetConnection> introductionsSent = new HashSet<NetConnection>();
|
||||
private Bimap<long, NetConnection> peers = new Bimap<long, NetConnection>();
|
||||
public const int defaultPort = 24642;
|
||||
private NetServer server;
|
||||
|
||||
public override int connectionsCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.server == null)
|
||||
return 0;
|
||||
return this.server.ConnectionsCount;
|
||||
}
|
||||
}
|
||||
|
||||
public CustomLidgrenServer(IGameServer gameServer)
|
||||
: base(gameServer)
|
||||
{
|
||||
}
|
||||
|
||||
public override string getUserName(long farmerId)
|
||||
{
|
||||
if (!this.peers.ContainsLeft(farmerId))
|
||||
return (string)null;
|
||||
return this.peers[farmerId].RemoteEndPoint.Address.ToString();
|
||||
}
|
||||
|
||||
public override void setPrivacy(ServerPrivacy privacy)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool canAcceptIPConnections()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool connected()
|
||||
{
|
||||
return this.server != null;
|
||||
}
|
||||
|
||||
public override void initialize()
|
||||
{
|
||||
Console.WriteLine("Starting LAN server");
|
||||
NetPeerConfiguration config = new NetPeerConfiguration("StardewValley");
|
||||
config.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
|
||||
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
|
||||
config.Port = 24642;
|
||||
config.ConnectionTimeout = 30f;
|
||||
config.PingInterval = 5f;
|
||||
config.MaximumConnections = ModCore.multiplayer.playerLimit * 2;
|
||||
config.MaximumTransmissionUnit = 1200;
|
||||
this.server = new NetServer(config);
|
||||
this.server.Start();
|
||||
}
|
||||
|
||||
public override void stopServer()
|
||||
{
|
||||
Console.WriteLine("Stopping LAN server");
|
||||
this.server.Shutdown("Server shutting down...");
|
||||
this.server.FlushSendQueue();
|
||||
this.introductionsSent.Clear();
|
||||
this.peers.Clear();
|
||||
}
|
||||
|
||||
public override void receiveMessages()
|
||||
{
|
||||
NetIncomingMessage netIncomingMessage;
|
||||
while ((netIncomingMessage = this.server.ReadMessage()) != null)
|
||||
{
|
||||
int i = (int)netIncomingMessage.MessageType;
|
||||
//ModCore.monitor.Log("Message Type: " + i.ToString());
|
||||
switch (netIncomingMessage.MessageType)
|
||||
{
|
||||
case NetIncomingMessageType.WarningMessage:
|
||||
case NetIncomingMessageType.ErrorMessage:
|
||||
case NetIncomingMessageType.DebugMessage:
|
||||
string str = netIncomingMessage.ReadString();
|
||||
Console.WriteLine("{0}: {1}", (object)netIncomingMessage.MessageType, (object)str);
|
||||
Game1.debugOutput = str;
|
||||
break;
|
||||
case NetIncomingMessageType.DiscoveryRequest:
|
||||
if (Game1.options.ipConnectionsEnabled)
|
||||
{
|
||||
this.sendVersionInfo(netIncomingMessage);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NetIncomingMessageType.StatusChanged:
|
||||
this.statusChanged(netIncomingMessage);
|
||||
break;
|
||||
case NetIncomingMessageType.ConnectionApproval:
|
||||
if (Game1.options.ipConnectionsEnabled)
|
||||
{
|
||||
netIncomingMessage.SenderConnection.Approve();
|
||||
break;
|
||||
}
|
||||
netIncomingMessage.SenderConnection.Deny();
|
||||
break;
|
||||
case NetIncomingMessageType.Data:
|
||||
//ModCore.monitor.Log("GOT DATA~~");
|
||||
this.parseDataMessageFromClient(netIncomingMessage);
|
||||
break;
|
||||
default:
|
||||
//ModCore.monitor.Log(netIncomingMessage.ToString());
|
||||
break;
|
||||
}
|
||||
this.server.Recycle(netIncomingMessage);
|
||||
}
|
||||
foreach (NetConnection netConnection in this.server.Connections)
|
||||
{
|
||||
NetConnection conn = netConnection;
|
||||
if (conn.Status == NetConnectionStatus.Connected && !this.introductionsSent.Contains(conn))
|
||||
{
|
||||
this.gameServer.sendAvailableFarmhands("", (Action<OutgoingMessage>)(msg => this.sendMessage(conn, msg)));
|
||||
this.introductionsSent.Add(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendVersionInfo(NetIncomingMessage message)
|
||||
{
|
||||
NetOutgoingMessage message1 = this.server.CreateMessage();
|
||||
message1.Write(ModCore.multiplayer.protocolVersion);
|
||||
message1.Write("StardewValley");
|
||||
this.server.SendDiscoveryResponse(message1, message.SenderEndPoint);
|
||||
}
|
||||
|
||||
private void statusChanged(NetIncomingMessage message)
|
||||
{
|
||||
switch ((NetConnectionStatus)message.ReadByte())
|
||||
{
|
||||
case NetConnectionStatus.Disconnected:
|
||||
case NetConnectionStatus.Disconnecting:
|
||||
if (!this.peers.ContainsRight(message.SenderConnection))
|
||||
break;
|
||||
this.playerDisconnected(this.peers[message.SenderConnection]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void playerDisconnected(long disconnectee)
|
||||
{
|
||||
base.playerDisconnected(disconnectee);
|
||||
this.introductionsSent.Remove(this.peers[disconnectee]);
|
||||
this.peers.RemoveLeft(disconnectee);
|
||||
}
|
||||
|
||||
private void parseDataMessageFromClient(NetIncomingMessage dataMsg)
|
||||
{
|
||||
//ModCore.monitor.Log("DATA MSG: "+dataMsg.ToString());
|
||||
NetConnection peer = dataMsg.SenderConnection;
|
||||
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);
|
||||
int type = message.MessageType;
|
||||
ModCore.monitor.Log("INCOMING MESSAGE TYPE: "+type.ToString());
|
||||
if (this.peers.ContainsLeft(message.FarmerID) && this.peers[message.FarmerID] == peer)
|
||||
this.gameServer.processIncomingMessage(message);
|
||||
else if ((int)message.MessageType == 2)
|
||||
{
|
||||
NetFarmerRoot farmer = ModCore.multiplayer.readFarmer(message.Reader);
|
||||
this.gameServer.checkFarmhandRequest("", farmer, (msg => this.sendMessage(peer, msg)), (Action)(() => this.peers[farmer.Value.UniqueMultiplayerID] = peer));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void sendMessage(long peerId, OutgoingMessage message)
|
||||
{
|
||||
if (!this.peers.ContainsLeft(peerId))
|
||||
return;
|
||||
this.sendMessage(this.peers[peerId], message);
|
||||
}
|
||||
|
||||
protected void sendMessage(NetConnection connection, OutgoingMessage message)
|
||||
{
|
||||
NetOutgoingMessage message1 = this.server.CreateMessage();
|
||||
using (NetBufferWriteStream bufferWriteStream = new NetBufferWriteStream((NetBuffer)message1))
|
||||
{
|
||||
using (BinaryWriter writer = new BinaryWriter((Stream)bufferWriteStream))
|
||||
message.Write(writer);
|
||||
}
|
||||
int num = (int)this.server.SendMessage(message1, connection, NetDeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
|
||||
public override void setLobbyData(string key, string value)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{8DB124E3-E892-4E7C-A782-2DA47771338C}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ModdedUtilitiesNetworking</RootNamespace>
|
||||
<AssemblyName>ModdedUtilitiesNetworking</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="GalaxyCSharp">
|
||||
<HintPath>..\..\..\..\..\..\..\Desktop\GalaxyCSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Lidgren.Network, Version=3.6.0.1625, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Stardew Valley\Lidgren.Network.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Class1.cs" />
|
||||
<Compile Include="Framework\Clients\CustomGalaxyClient.cs" />
|
||||
<Compile Include="Framework\Clients\CustomLidgrenClient.cs" />
|
||||
<Compile Include="Framework\Delegates\DelegateInfo.cs" />
|
||||
<Compile Include="Framework\Extentions\BinaryReadWriteExtentions.cs" />
|
||||
<Compile Include="Framework\Messages\OutgoingMessageBase.cs" />
|
||||
<Compile Include="Framework\CustomMultiplayer.cs" />
|
||||
<Compile Include="Framework\Network\NetBufferReadStream.cs" />
|
||||
<Compile Include="Framework\Network\NetBufferWriteStream.cs" />
|
||||
<Compile Include="Framework\Servers\CustomGameServer.cs" />
|
||||
<Compile Include="Framework\Servers\CustomLidgrenServer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="manifest.json" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ModdedUtilitiesNetworking")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ModdedUtilitiesNetworking")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("8db124e3-e892-4e7c-a782-2da47771338c")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"Name": "ModdedUtilitiesNetworking",
|
||||
"Author": "Alpha_Omegasis",
|
||||
"Version": "0.0.1",
|
||||
"Description": "A dumb attempt at networking",
|
||||
"UniqueID": "Omegasis.ModdedUtilitiesNetworking",
|
||||
"EntryDll": "ModdedUtilitiesNetworking.dll",
|
||||
"MinimumApiVersion": "2.0",
|
||||
"UpdateKeys": [ "" ]
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Pathoschild.Stardew.ModBuildConfig" version="2.1.0-beta-20180428" targetFramework="net461" />
|
||||
</packages>
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NetworkMod
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>60730e3f-3448-4f0b-9a84-9aa0488061e5</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>NetworkMod</RootNamespace>
|
||||
<AssemblyName>NetworkMod</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System"/>
|
||||
|
||||
<Reference Include="System.Core"/>
|
||||
<Reference Include="System.Xml.Linq"/>
|
||||
<Reference Include="System.Data.DataSetExtensions"/>
|
||||
|
||||
|
||||
<Reference Include="Microsoft.CSharp"/>
|
||||
|
||||
<Reference Include="System.Data"/>
|
||||
|
||||
<Reference Include="System.Net.Http"/>
|
||||
|
||||
<Reference Include="System.Xml"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Class1.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("NetworkMod")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("NetworkMod")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("60730e3f-3448-4f0b-9a84-9aa0488061e5")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,37 @@
|
|||
using NetworkNightmare.Framework;
|
||||
using StardewModdingAPI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NetworkNightmare
|
||||
{
|
||||
public class NetworkNightmare : Mod
|
||||
{
|
||||
public static IModHelper helper;
|
||||
public static IMonitor monitor;
|
||||
|
||||
public override void Entry(IModHelper helper)
|
||||
{
|
||||
helper = this.Helper;
|
||||
monitor = this.Monitor;
|
||||
|
||||
StardewModdingAPI.Events.MultiplayerEvents.BeforeMainSync += MultiplayerEvents_BeforeMainSync;
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void MultiplayerEvents_BeforeMainSync(object sender, EventArgs e)
|
||||
{
|
||||
CustomMultiplayer player = new CustomMultiplayer();
|
||||
CustomMultiplayer.forceCustomMultiplayer(player);
|
||||
}
|
||||
|
||||
private void GameEvents_FirstUpdateTick(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using StardewModdingAPI;
|
||||
using StardewValley;
|
||||
using StardewValley.Network;
|
||||
|
||||
namespace NetworkNightmare.Framework
|
||||
{
|
||||
public class CustomMultiplayer : StardewValley.Multiplayer
|
||||
{
|
||||
public CustomMultiplayer() : base()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void processIncomingMessage(IncomingMessage msg)
|
||||
{
|
||||
base.processIncomingMessage(msg);
|
||||
}
|
||||
|
||||
public static bool forceCustomMultiplayer(CustomMultiplayer custom)
|
||||
{
|
||||
if (custom == null)
|
||||
{
|
||||
NetworkNightmare.monitor.Log("WELL I GIVE UP");
|
||||
}
|
||||
// Get a PropertyInfo of specific property type(T).GetProperty(....)
|
||||
IReflectedField<Multiplayer> propertyInfo = NetworkNightmare.helper.Reflection.GetField<Multiplayer>(typeof(StardewValley.Game1), "multiplayer",false);
|
||||
propertyInfo.SetValue(custom);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NetworkNightmare.Framework
|
||||
{
|
||||
public enum MultiplayerPacket
|
||||
{
|
||||
ReadFarmerRoot,
|
||||
UnusedByte1,
|
||||
ReceivePlayerIntroduction,
|
||||
ReadActiveLocation,
|
||||
ReadWarp,
|
||||
UnsedByte5,
|
||||
ReadLocation,
|
||||
ReadSpritesAtLocation,
|
||||
WarpNPCS,
|
||||
UnusedByte9,
|
||||
ReceiveChatMessage,
|
||||
UnusedByte11,
|
||||
ReceiveWorldState,
|
||||
ReceiveTeamDelta,
|
||||
ReceiveNewDaySync,
|
||||
ReceiveChatInfoMessage,
|
||||
Unused16,
|
||||
ReceiveFarmerGainExperience,
|
||||
ParseServerToClientsMessage,
|
||||
PlayerDisconnected
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{27DAB9BB-92E0-4FC1-BC79-F513CE1F3262}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>NetworkNightmare</RootNamespace>
|
||||
<AssemblyName>NetworkNightmare</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Class1.cs" />
|
||||
<Compile Include="Framework\CustomMultiplayer.cs" />
|
||||
<Compile Include="Framework\MultiplayerPacket.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="manifest.json" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("NetworkNightmare")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("NetworkNightmare")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("27dab9bb-92e0-4fc1-bc79-f513ce1f3262")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"Name": "Network Nightmare",
|
||||
"Author": "Alpha_Omegasis",
|
||||
"Version": "0.0.1",
|
||||
"Description": "A dumb experiment.",
|
||||
"UniqueID": "Omegasis.NetworkNightmare",
|
||||
"EntryDll": "NetworkNightmare.dll",
|
||||
"MinimumApiVersion": "2.0",
|
||||
"UpdateKeys": [ "" ]
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Pathoschild.Stardew.ModBuildConfig" version="2.1.0-beta-20180428" targetFramework="net461" />
|
||||
</packages>
|
|
@ -76,6 +76,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebugSandBoxAndReferences",
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdditionalCropsFramework", "AdditionalCropsFramework\AdditionalCropsFramework.csproj", "{C5F88D48-EA20-40CD-91E2-C8725DC11795}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModdedUtilitiesNetworking", "ModdedUtilitiesNetworking\ModdedUtilitiesNetworking.csproj", "{8DB124E3-E892-4E7C-A782-2DA47771338C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -398,6 +400,18 @@ Global
|
|||
{C5F88D48-EA20-40CD-91E2-C8725DC11795}.x86|Any CPU.Build.0 = x86|Any CPU
|
||||
{C5F88D48-EA20-40CD-91E2-C8725DC11795}.x86|x86.ActiveCfg = x86|x86
|
||||
{C5F88D48-EA20-40CD-91E2-C8725DC11795}.x86|x86.Build.0 = x86|x86
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.x86|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.x86|Any CPU.Build.0 = Release|Any CPU
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.x86|x86.ActiveCfg = Release|Any CPU
|
||||
{8DB124E3-E892-4E7C-A782-2DA47771338C}.x86|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -168,8 +168,8 @@ namespace StardewSymphonyRemastered.Framework
|
|||
var farm = (Farm)Game1.getLocationFromName("Farm");
|
||||
foreach(var building in farm.buildings)
|
||||
{
|
||||
locations.Add(building.nameOfIndoors.Value);
|
||||
StardewSymphony.ModMonitor.Log("Adding in song triggers for location: " + building.nameOfIndoors.Value);
|
||||
locations.Add(building.nameOfIndoors);
|
||||
StardewSymphony.ModMonitor.Log("Adding in song triggers for location: " + building.nameOfIndoors);
|
||||
}
|
||||
}
|
||||
catch(Exception err)
|
||||
|
|
|
@ -223,7 +223,7 @@ namespace StardustCore.Serialization
|
|||
foreach (Building building in Game1.getFarm().buildings)
|
||||
{
|
||||
|
||||
GameLocation loc =Game1.getLocationFromName(building.nameOfIndoors.Value,true);
|
||||
GameLocation loc =Game1.getLocationFromName(building.nameOfIndoors,true);
|
||||
ModCore.ModMonitor.Log("Cleaning up farm building: "+loc.uniqueName.Value);
|
||||
int i = loc.objects.Pairs.Count();
|
||||
int j = 0;
|
||||
|
@ -248,7 +248,7 @@ namespace StardustCore.Serialization
|
|||
SerializerDataNode t;
|
||||
if(acceptedTypes.ContainsKey((v as CoreObject).serializationName)){
|
||||
acceptedTypes.TryGetValue((v as CoreObject).serializationName, out t);
|
||||
string s = Path.Combine(building.nameOfIndoors.Value, "Chest,"+Convert.ToString( (int)obj.Key.X)+","+Convert.ToString((int)obj.Key.Y));
|
||||
string s = Path.Combine(building.nameOfIndoors, "Chest,"+Convert.ToString( (int)obj.Key.X)+","+Convert.ToString((int)obj.Key.Y));
|
||||
string s2 = Path.Combine(ModCore.SerializationManager.storageContainerPath, s);
|
||||
if (!Directory.Exists(s)) Directory.CreateDirectory(s2);
|
||||
t.serializeToContainer.Invoke(v, s2);
|
||||
|
|
|
@ -119,6 +119,7 @@
|
|||
<ItemGroup>
|
||||
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\deploy.targets" />
|
||||
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.1.0-beta-20180428\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
|
||||
|
|
Loading…
Reference in New Issue