private void SendModMessage(string messageText, string messageType, string receiverModID, long receiverID) { AuthDewMessage message = new AuthDewMessage(); message.messageSenderId = senderId; message.messageBody = messageText; this.Helper.Multiplayer.SendMessage <AuthDewMessage>(message, messageType, modIDs: new[] { receiverModID }, playerIDs: new[] { receiverID }); this.Monitor.Log($"sent message of type {messageType}, senderID: {message.messageSenderId}, " + $"and body |{message.messageBody}| to player {receiverID}"); }
private bool IsApiCompatible(AuthDewMessage message) { if (message.messageApiMajor >= 1 && message.messageApiMinor >= 0 && message.messageApiPatch >= 0) { return(true); } else { return(false); } }
private void OnModMessageReceived(object sender, ModMessageReceivedEventArgs e) { AuthDewMessage message = e.ReadAs <AuthDewMessage>(); // CLIENT: confirm source (host, modname), receive authRequest, inviteCodeRequest, newAuthCode // DEBUG/DEVELOPMENT STUFF - TODO: remove when testing done. this.Monitor.Log($"received message of type {e.Type} by mod {e.FromModID} from " + $"player {e.FromPlayerID}, is the player host? " + $"{this.Helper.Multiplayer.GetConnectedPlayer(e.FromPlayerID).IsHost}"); this.Monitor.Log($"message contents: API {message.messageApiMajor}.{message.messageApiMinor}." + $"{message.messageApiPatch}, " + $"senderID: {message.messageSenderId}, " + $"body: {message.messageBody}"); // if this is run by host, then don't do anything if (Context.IsMainPlayer) { if (!isServer) { this.Monitor.Log("WARNING: Player is main player, AuthDew client functionality disabled."); isServer = true; } return; } // if message is not from host, also don't do anything (return) if (!this.Helper.Multiplayer.GetConnectedPlayer(e.FromPlayerID).IsHost) { this.Monitor.Log($"received message from non-host player {e.FromPlayerID} - ignoring"); return; } // TODO: make this check optional to allow other server software to interact with the API? // Or add this as an option to client and server to open it up? if (e.FromModID != "thfr.AuthDew-server") { this.Monitor.Log($"received message from a mod that's not thfr.AuthDew-server: {e.FromModID}"); return; } if (!IsApiCompatible(message)) { if (ApiCompatibleBool) { this.Monitor.Log($"ERROR: received message with incompatible API version " + $"{message.messageApiMajor}." + $"{message.messageApiMinor}." + $"{message.messageApiPatch}"); ApiCompatibleBool = false; } // send message to sending server indicating API incompatibility SendModMessage("", "ApiIncompatible", "thfr.AuthDew-server", e.FromPlayerID); return; } isServer = false; ApiCompatibleBool = true; // parse message switch (e.Type) { case "authRequest": // check if there's an entry for the server in clientAuthTable // - if not, send some noAuthAvailable code // - if exists, send the corresponding code to the server as authResponse if (clientAuthTable.ContainsKey(message.messageSenderId)) { // Check if the farmerName exists in the clientAuthTable's entry for this server if (!clientAuthTable[message.messageSenderId].ContainsKey(Game1.player.Name)) { this.Monitor.Log($"ERROR: no entry for farmer {Game1.player.Name} " + $"to respond to authRequest from server {e.FromPlayerID}"); break; } // send the authCode from lookup in the nested dictionary to server SendModMessage(clientAuthTable[message.messageSenderId][Game1.player.Name], "authResponse", "thfr.AuthDew-server", e.FromPlayerID); } else { SendModMessage("", "noAuthAvailable", "thfr.AuthDew-server", e.FromPlayerID); } break; case "inviteCodeRequest": // check if there's an entry for the server in inviteCodeTable // - if not, send some noInviteCodeAvailable code // - if exists, send the corresponding code to the server as inviteCodeResponse if (inviteCodeTable.ContainsKey(message.messageSenderId)) { SendModMessage(inviteCodeTable[message.messageSenderId], "inviteCodeResponse", "thfr.AuthDew-server", e.FromPlayerID); } else { SendModMessage("", "noInviteCodeAvailable", "thfr.AuthDew-server", e.FromPlayerID); } break; case "createNewAuth": // take e.ReadAs<MPAuthModMessage>().messageBody and store in clientAuthTable for this server // then send confirmNewAuth to server this.Monitor.Log($"received instruction to create new auth entry for the connected host: " + $"{message.messageSenderId}, with body: {message.messageBody}"); this.Monitor.Log($"adding server {e.FromPlayerID} as pending auth creation"); pendingAuthCreationServer = new KeyValuePair <long, KeyValuePair <string, KeyValuePair <string, string> > > ( e.FromPlayerID, new KeyValuePair <string, KeyValuePair <string, string> >(message.messageSenderId, new KeyValuePair <string, string>(Game1.player.Name, message.messageBody)) ); break; // TODO: add handler for "ApiIncompatible" message type default: this.Monitor.Log($"received message of unknown type from {e.FromPlayerID}"); break; } }