Example #1
0
        private void OnModMessageReceived(object sender, ModMessageReceivedEventArgs e)
        {
            if (e.FromModID != this.ModManifest.UniqueID)
            {
                return;
            }

            ModEntry.Log($"[{(Context.IsMainPlayer ? "host" : "farmhand")}] Received {e.Type} from {e.FromPlayerID}.", LogLevel.Trace);

            switch (e.Type)
            {
            // farmhand requested metadata
            case MessageId.RequestMetadata:
                if (Context.IsMainPlayer)
                {
                    // client requests settings and state, send it:
                    InitResponseMessage response = new InitResponseMessage
                    {
                        Settings   = DeepWoodsSettings.Settings,
                        State      = DeepWoodsSettings.DeepWoodsState,
                        LevelNames = Game1.locations.OfType <DeepWoods>().Select(p => p.Name).ToArray()
                    };
                    ModEntry.SendMessage(response, MessageId.Metadata, e.FromPlayerID);
                }
                break;

            // host sent metadata
            case MessageId.Metadata:
                if (!Context.IsMainPlayer)
                {
                    InitResponseMessage response = e.ReadAs <InitResponseMessage>();
                    DeepWoodsSettings.Settings       = response.Settings;
                    DeepWoodsSettings.DeepWoodsState = response.State;
                    ModEntry.DeepWoodsInitServerAnswerReceived(response.LevelNames);
                }
                break;

            // farmhand requested that we load and activate a DeepWoods level
            case MessageId.RequestWarp:
                if (Context.IsMainPlayer)
                {
                    // load level
                    int       level     = e.ReadAs <int>();
                    DeepWoods deepWoods = DeepWoodsManager.AddDeepWoodsFromObelisk(level);

                    // send response
                    WarpMessage response = new WarpMessage
                    {
                        Level         = deepWoods.Level,
                        Name          = deepWoods.Name,
                        EnterLocation = new Vector2(deepWoods.enterLocation.Value.X, deepWoods.enterLocation.Value.Y)
                    };
                    ModEntry.SendMessage(response, MessageId.Warp, e.FromPlayerID);
                }
                break;

            // host loaded area for warp
            case MessageId.Warp:
                if (!Context.IsMainPlayer)
                {
                    WarpMessage data = e.ReadAs <WarpMessage>();

                    DeepWoodsManager.AddBlankDeepWoodsToGameLocations(data.Name);
                    DeepWoodsManager.WarpFarmerIntoDeepWoodsFromServerObelisk(data.Name, data.EnterLocation);
                }
                break;

            // host sent 'lowest level reached' update
            case MessageId.SetLowestLevelReached:
                if (!Context.IsMainPlayer)
                {
                    DeepWoodsState.LowestLevelReached = e.ReadAs <int>();
                }
                break;

            // host sent 'received stardrop from unicorn' update
            case MessageId.SetUnicornStardropReceived:
                if (Context.IsMainPlayer)
                {
                    DeepWoodsState.PlayersWhoGotStardropFromUnicorn.Add(e.FromPlayerID);
                }
                break;

            // host added/removed location
            case MessageId.AddLocation:
                if (!Context.IsMainPlayer)
                {
                    string name = e.ReadAs <string>();
                    DeepWoodsManager.AddBlankDeepWoodsToGameLocations(name);
                }
                break;

            case MessageId.RemoveLocation:
                if (!Context.IsMainPlayer)
                {
                    string name = e.ReadAs <string>();
                    DeepWoodsManager.RemoveDeepWoodsFromGameLocations(name);
                }
                break;

            default:
                ModEntry.Log("   ignored unknown type.", LogLevel.Trace);
                break;
            }
        }
            // This method is also called by the patch in DeepWoodsMTNCompatibilityMod.
            // We return false when we handled this message, so Harmony will cancel the original MTN handler.
            private static bool InternalProcessIncomingMessage(IncomingMessage msg)
            {
                if (msg.MessageType == Settings.Network.DeepWoodsMessageId)
                {
                    int deepwoodsMessageType = msg.Reader.ReadInt32();
                    int randId = Game1.random.Next();

                    ModEntry.Log("InterceptProcessIncomingMessage[" + randId + "], master id: " + Game1.MasterPlayer.UniqueMultiplayerID + ", local id: " + Game1.player.UniqueMultiplayerID + ", msg.FarmerID: " + msg.FarmerID + ", deepwoodsMessageType: " + deepwoodsMessageType, StardewModdingAPI.LogLevel.Debug);

                    Farmer who = Game1.getFarmer(msg.FarmerID);
                    if (who == null || who == Game1.player)
                    {
                        ModEntry.Log(" who is null or local!", StardewModdingAPI.LogLevel.Warn);
                        return(true); // execute original
                    }

                    if (deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_INIT)
                    {
                        ModEntry.Log(" [" + randId + "] deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_INIT", StardewModdingAPI.LogLevel.Debug);
                        if (Game1.IsMasterGame)
                        {
                            // Client requests settings and state, send it:
                            List <string> deepWoodsLevelNames = new List <string>();
                            foreach (var location in Game1.locations)
                            {
                                if (location is DeepWoods deepWoods)
                                {
                                    deepWoodsLevelNames.Add(deepWoods.Name);
                                }
                            }

                            object[] data = new object[deepWoodsLevelNames.Count + 4];
                            data[0] = NETWORK_MESSAGE_DEEPWOODS_INIT;
                            data[1] = JsonConvert.SerializeObject(Settings);
                            data[2] = JsonConvert.SerializeObject(DeepWoodsState);
                            data[3] = (int)deepWoodsLevelNames.Count;
                            for (int i = 0; i < deepWoodsLevelNames.Count; i++)
                            {
                                data[i + 4] = deepWoodsLevelNames[i];
                            }

                            ModEntry.Log(" [" + randId + "] Client requests settings and state, deepWoodsLevelNames.Count: " + deepWoodsLevelNames.Count + ", deepWoodsLevelNames: " + String.Join(", ", deepWoodsLevelNames.ToArray()), StardewModdingAPI.LogLevel.Debug);
                            who.queueMessage(Settings.Network.DeepWoodsMessageId, Game1.MasterPlayer, data);
                        }
                        else
                        {
                            // Server sent us settings and state!
                            Settings       = JsonConvert.DeserializeObject <DeepWoodsSettings>(msg.Reader.ReadString());
                            DeepWoodsState = JsonConvert.DeserializeObject <DeepWoodsStateData>(msg.Reader.ReadString());
                            int           numDeepWoodsLevelNames = msg.Reader.ReadInt32();
                            List <string> deepWoodsLevelNames    = new List <string>();
                            for (int i = 0; i < numDeepWoodsLevelNames; i++)
                            {
                                deepWoodsLevelNames.Add(msg.Reader.ReadString());
                            }
                            ModEntry.Log(" [" + randId + "] Server sent us settings and state, deepWoodsLevelNames.Count: " + deepWoodsLevelNames.Count + ", deepWoodsLevelNames: " + String.Join(", ", deepWoodsLevelNames.ToArray()), StardewModdingAPI.LogLevel.Debug);
                            ModEntry.DeepWoodsInitServerAnswerReceived(deepWoodsLevelNames);
                        }
                    }
                    else
                    {
                        if (!Game1.IsMasterGame && !ModEntry.IsDeepWoodsGameRunning)
                        {
                            if (ModEntry.HasRequestedInitMessageFromServer)
                            {
                                ModEntry.Log("Got message from server before init message!", StardewModdingAPI.LogLevel.Warn);
                            }
                            else
                            {
                                ModEntry.Log("Got message from server before init message, never sent init message request!", StardewModdingAPI.LogLevel.Warn);
                            }
                        }
                        if (deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_WARP)
                        {
                            ModEntry.Log(" [" + randId + "] deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_WARP", StardewModdingAPI.LogLevel.Debug);
                            DeepWoodsWarpMessageData data = ReadDeepWoodsWarpMessage(msg.Reader);
                            if (Game1.IsMasterGame)
                            {
                                // Client requests that we load and activate a specific DeepWoods level they want to warp into.
                                DeepWoods deepWoods = DeepWoodsManager.AddDeepWoodsFromObelisk(data.Level);
                                // Send message to client telling them we have the level ready.
                                ModEntry.Log(" [" + randId + "] Client requests that we load and activate a specific DeepWoods level they want to warp into: data.Level:" + data.Level, StardewModdingAPI.LogLevel.Debug);
                                who.queueMessage(Settings.Network.DeepWoodsMessageId, Game1.MasterPlayer, new object[] { NETWORK_MESSAGE_DEEPWOODS_WARP, deepWoods.level.Value, deepWoods.Name, new Vector2(deepWoods.enterLocation.Value.X, deepWoods.enterLocation.Value.Y) });
                            }
                            else
                            {
                                // Server informs us that we can warp now!
                                ModEntry.Log(" [" + randId + "] Server informs us that we can warp now: data.Level:" + data.Level + ", data.Name:" + data.Name, StardewModdingAPI.LogLevel.Debug);
                                DeepWoodsManager.AddBlankDeepWoodsToGameLocations(data.Name);
                                DeepWoodsManager.WarpFarmerIntoDeepWoodsFromServerObelisk(data.Name, data.EnterLocation);
                            }
                        }
                        else if (deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_LEVEL)
                        {
                            ModEntry.Log(" [" + randId + "] deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_LEVEL", StardewModdingAPI.LogLevel.Debug);
                            if (!Game1.IsMasterGame && who == Game1.MasterPlayer)
                            {
                                DeepWoodsState.LowestLevelReached = msg.Reader.ReadInt32();
                                ModEntry.Log(" [" + randId + "] DeepWoodsState.LowestLevelReached: " + DeepWoodsState.LowestLevelReached, StardewModdingAPI.LogLevel.Debug);
                            }
                        }
                        else if (deepwoodsMessageType == NETWORK_MESSAGE_RCVD_STARDROP_FROM_UNICORN)
                        {
                            ModEntry.Log(" [" + randId + "] deepwoodsMessageType == NETWORK_MESSAGE_RCVD_STARDROP_FROM_UNICORN", StardewModdingAPI.LogLevel.Debug);
                            if (Game1.IsMasterGame)
                            {
                                DeepWoodsState.PlayersWhoGotStardropFromUnicorn.Add(who.UniqueMultiplayerID);
                            }
                        }
                        else if (deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_ADDREMOVE)
                        {
                            ModEntry.Log(" [" + randId + "] deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_ADDREMOVE", StardewModdingAPI.LogLevel.Debug);
                            if (!Game1.IsMasterGame)
                            {
                                bool   added = msg.Reader.ReadByte() != 0;
                                string name  = msg.Reader.ReadString();
                                ModEntry.Log(" [" + randId + "] added: " + added + ", name: " + name, StardewModdingAPI.LogLevel.Debug);
                                if (added)
                                {
                                    DeepWoodsManager.AddBlankDeepWoodsToGameLocations(name);
                                }
                                else
                                {
                                    DeepWoodsManager.RemoveDeepWoodsFromGameLocations(name);
                                }
                            }
                        }
                        else
                        {
                            ModEntry.Log(" [" + randId + "] unknown deepwoodsMessageType: " + deepwoodsMessageType + "!", StardewModdingAPI.LogLevel.Warn);
                            return(true); // execute original
                        }
                    }

                    return(false); // don't execute original
                }

                return(true); // execute original
            }