Beispiel #1
0
        /// <summary>
        /// Writes a GameClock object to the database
        /// </summary>
        /// <returns>bool indicating success</returns>
        /// <param name="gameID">Game (bucket) to write to</param>
        /// <param name="gc">GameClock to write</param>
        public static bool DatabaseWrite_Clock(string gameID, GameClock gc)
        {
            var rClock         = new RiakObject(gameID, "gameClock", gc);
            var putClockResult = Globals_Server.rClient.Put(rClock);

            if (!putClockResult.IsSuccess)
            {
                Globals_Server.logError("Write failed: GameClock to bucket " + rClock.Bucket + ": " + putClockResult.ErrorMessage);
            }


            return(putClockResult.IsSuccess);
        }
Beispiel #2
0
        public static bool DatabaseWrite_Client(string gameID, Client client)
        {
            Client_Serialized clientSer = new Client_Serialized(client);
            var rString         = new RiakObject(gameID, client.username, clientSer);
            var putStringResult = Globals_Server.rClient.Put(rString);

            if (!putStringResult.IsSuccess)
            {
                Globals_Server.logError("Write failed: String variable " + clientSer.user + " to bucket " + rString.Bucket);
            }

            return(putStringResult.IsSuccess);
        }
Beispiel #3
0
        /// <summary>
        /// Writes a key list (List object) to the database
        /// </summary>
        /// <returns>bool indicating success</returns>
        /// <param name="gameID">Game (bucket) to write to</param>
        /// <par	am name="k">key of key list</param>
        /// <param name="kl">key list to write</param>
        public static bool DatabaseWrite_KeyList <T>(string gameID, string k, List <T> kl)
        {
            Console.WriteLine("Writing key list " + k + " to bucket " + gameID);
            RiakObject rList         = new RiakObject(gameID, k);
            var        putListResult = Globals_Server.rClient.Put(rList);

            if (!putListResult.IsSuccess)
            {
                Globals_Server.logError("Write failed: Key list " + rList.Key + " to bucket " + rList.Bucket);
            }

            return(putListResult.IsSuccess);
        }
Beispiel #4
0
        /// <summary>
        /// Writes a string variable to the database
        /// </summary>
        /// <returns>bool indicating success</returns>
        /// <param name="gameID">Game (bucket) to write to</param>
        /// <param name="key">Database key to use</param>
        /// <param name="pcID">string to write</param>
        public static bool DatabaseWrite_String(string gameID, string key, string pcID)
        {
            pcID = "\"" + pcID + "\"";

            var rString         = new RiakObject(gameID, key, pcID);
            var putStringResult = Globals_Server.rClient.Put(rString);

            if (!putStringResult.IsSuccess)
            {
                Globals_Server.logError("Write failed: String variable " + key + " to bucket " + rString.Bucket);
            }

            return(putStringResult.IsSuccess);
        }
Beispiel #5
0
        /// <summary>
        /// Writes a Province or Province_Serialised object to the database
        /// </summary>
        /// <returns>bool indicating success</returns>
        /// <param name="gameID">Game (bucket) to write to</param>
        /// <param name="p">Province to write</param>
        /// <param name="ps">Province_Serialised to write</param>
        public static bool DatabaseWrite_Province(string gameID, Province p = null, Province_Serialised ps = null)
        {
            if (p != null)
            {
                // convert Province into Province_Serialised
                ps = DatabaseWrite.Province_serialise(p);
            }

            var rProv         = new RiakObject(gameID, ps.id, ps);
            var putProvResult = Globals_Server.rClient.Put(rProv);

            if (!putProvResult.IsSuccess)
            {
                Globals_Server.logError("Write failed: Province " + rProv.Key + " to bucket " + rProv.Bucket);
            }

            return(putProvResult.IsSuccess);
        }
Beispiel #6
0
        /// <summary>
        /// Writes a Kingdom or Kingdom_Serialised object to the database
        /// </summary>
        /// <returns>bool indicating success</returns>
        /// <param name="gameID">Game (bucket) to write to</param>
        /// <param name="k">Kingdom to write</param>
        /// <param name="ks">Kingdom_Serialised to write</param>
        public static bool DatabaseWrite_Kingdom(string gameID, Kingdom k = null, Kingdom_Serialised ks = null)
        {
            if (k != null)
            {
                // convert Kingdom into Kingdom_Serialised
                ks = DatabaseWrite.Kingdom_serialise(k);
            }

            var rKing         = new RiakObject(gameID, ks.id, ks);
            var putKingResult = Globals_Server.rClient.Put(rKing);

            if (!putKingResult.IsSuccess)
            {
                Globals_Server.logError("Write failed: Kingdom " + rKing.Key + " to bucket " + rKing.Bucket);
            }

            return(putKingResult.IsSuccess);
        }
Beispiel #7
0
        /// <summary>
        /// Writes a Position or Position_Serialised object to the database
        /// </summary>
        /// <returns>bool indicating success</returns>
        /// <param name="gameID">Game (bucket) to write to</param>
        /// <param name="p">Position to write</param>
        /// <param name="ps">Position_Serialised to write</param>
        public static bool DatabaseWrite_Position(string gameID, Position p = null, Position_Serialised ps = null)
        {
            if (p != null)
            {
                // convert Position into Position_Serialised
                ps = DatabaseWrite.Position_serialise(p);
            }

            var rPos         = new RiakObject(gameID, ps.id.ToString(), ps);
            var putPosResult = Globals_Server.rClient.Put(rPos);

            if (!putPosResult.IsSuccess)
            {
                Globals_Server.logError("Write failed: Position " + rPos.Key + " to bucket " + rPos.Bucket);
            }

            return(putPosResult.IsSuccess);
        }
Beispiel #8
0
        /// <summary>
        /// Writes a HexMapGraph edges collection to the database
        /// </summary>
        /// <returns>bool indicating success</returns>
        /// <param name="gameID">Game (bucket) to write to</param>
        /// <param name="map">HexMapGraph containing edges collection to write</param>
        /// <param name="edges">Edges collection to write</param>
        public static bool DatabaseWrite_MapEdges(string gameID, HexMapGraph map = null, List <TaggedEdge <string, string> > edges = null)
        {
            if (map != null)
            {
                // convert Language into Language_Serialised
                edges = DatabaseWrite.EdgeCollection_serialise(map.myMap.Edges.ToList());
            }

            var rMapE         = new RiakObject(gameID, "mapEdges", edges);
            var putMapResultE = Globals_Server.rClient.Put(rMapE);

            if (!putMapResultE.IsSuccess)
            {
                Globals_Server.logError("Write failed: Map edges collection " + rMapE.Key + " to bucket " + rMapE.Bucket);
            }

            return(putMapResultE.IsSuccess);
        }
Beispiel #9
0
        /// <summary>
        /// Writes a Fief or Fief_Serialised object to the database
        /// </summary>
        /// <returns>bool indicating success</returns>
        /// <param name="gameID">Game (bucket) to write to</param>
        /// <param name="f">Fief to write</param>
        /// <param name="fs">Fief_Serialised to write</param>
        public static bool DatabaseWrite_Fief(string gameID, Fief f = null, Fief_Serialised fs = null)
        {
            if (f != null)
            {
                // convert Fief to Fief_Serialised
                fs = DatabaseWrite.Fief_serialise(f);
            }

            var rFief         = new RiakObject(gameID, fs.id, fs);
            var putFiefResult = Globals_Server.rClient.Put(rFief);

            if (!putFiefResult.IsSuccess)
            {
                Globals_Server.logError("Write failed: Fief " + rFief.Key + " to bucket " + rFief.Bucket);
            }

            return(putFiefResult.IsSuccess);
        }
Beispiel #10
0
        //public static void SendViaProto(global::ProtoMessage.ProtoMessage m, NetConnection conn, bool isPCL, NetEncryption alg = null)
        //{
        //    Contract.Requires(m != null && conn != null);
        //    NetOutgoingMessage msg = server.CreateMessage();
        //    MemoryStream ms = new MemoryStream();
        //    Serializer.SerializeWithLengthPrefix<global::ProtoMessage.ProtoMessage>(ms, m, PrefixStyle.Fixed32);
        //    msg.Write(ms.GetBuffer());
        //    if (alg != null)
        //    {
        //        msg.Encrypt(alg);
        //    }
        //    server.SendMessage(msg, conn, NetDeliveryMethod.ReliableOrdered);
        //    server.FlushSendQueue();
        //}

        /// <summary>
        /// Read a message, get the relevant reply and send to client
        /// </summary>
        /// <param name="m">Deserialised message from client</param>
        /// <param name="connection">Client's connecton</param>
        public void ProcessMessage(ProtoMessage m, NetConnection connection)
        {
            Contract.Requires(connection != null && m != null);
            Client client;

            clientConnections.TryGetValue(connection, out client);
            if (client == null)
            {
                NetOutgoingMessage errorMessage =
                    server.CreateMessage("There was a problem with the connection. Please try re-connecting");
                server.SendMessage(errorMessage, connection, NetDeliveryMethod.ReliableOrdered);
                string log = "Connection from peer " + connection.Peer.UniqueIdentifier +
                             " not found in client connections. Timestamp: " +
                             DateTime.Now.ToString(DateTimeFormatInfo.CurrentInfo);
                Globals_Server.logError(log);
                return;
            }
            var pc = client.myPlayerCharacter;

            if (pc == null || !pc.isAlive)
            {
                NetOutgoingMessage msg = server.CreateMessage("You have no valid PlayerCharacter!");
                server.SendMessage(msg, connection, NetDeliveryMethod.ReliableOrdered);
                server.FlushSendQueue();
            }
            else
            {
                Globals_Server.logEvent("From: " + clientConnections[connection].username +
                                        ": request = " + m.ActionType.ToString());
                ProtoMessage reply = Game.ActionController(m, client);
                // Set action type to ensure client knows which action invoked response
                if (reply == null)
                {
                    ProtoMessage invalid = new ProtoMessage(DisplayMessages.ErrorGenericMessageInvalid);
                    invalid.ActionType = Actions.Update;
                    reply = invalid;
                }
                else
                {
                    reply.ActionType = m.ActionType;
                }
                SendViaProto(reply, connection, client.alg);
            }
        }
Beispiel #11
0
        /// <summary>
        /// Writes a PlayerCharacter or PlayerCharacter_Serialised object to the database
        /// </summary>
        /// <returns>bool indicating success</returns>
        /// <param name="gameID">Game (bucket) to write to</param>
        /// <param name="pc">PlayerCharacter to write</param>
        /// <param name="pcs">PlayerCharacter_Serialised to write</param>
        public static bool DatabaseWrite_PC(string gameID, PlayerCharacter pc = null, PlayerCharacter_Serialised pcs = null)
        {
            if (pc != null)
            {
                // convert PlayerCharacter into PlayerCharacter_Serialised
                pcs = DatabaseWrite.PC_serialise(pc);
            }

            // write PlayerCharacter_Serialised to database
            var rPC         = new RiakObject(gameID, pcs.charID, pcs);
            var putPCresult = Globals_Server.rClient.Put(rPC);

            if (!putPCresult.IsSuccess)
            {
                Globals_Server.logError("Write failed: PC " + rPC.Key + " to bucket " + rPC.Bucket);
            }

            return(putPCresult.IsSuccess);
        }
Beispiel #12
0
        /// <summary>
        /// Writes a NonPlayerCharacter or NonPlayerCharacter_Serialised object to the database
        /// </summary>
        /// <returns>bool indicating success</returns>
        /// <param name="gameID">Game (bucket) to write to</param>
        /// <param name="npc">NonPlayerCharacter to write</param>
        /// <param name="npcs">NonPlayerCharacter_Serialised to write</param>
        public static bool DatabaseWrite_NPC(string gameID, NonPlayerCharacter npc = null, NonPlayerCharacter_Serialised npcs = null)
        {
            if (npc != null)
            {
                // convert NonPlayerCharacter into NonPlayerCharacter_Serialised
                npcs = DatabaseWrite.NPC_serialise(npc);
            }

            // write NonPlayerCharacter_Serialised to database
            var rNPC         = new RiakObject(gameID, npcs.charID, npcs);
            var putNPCresult = Globals_Server.rClient.Put(rNPC);

            if (!putNPCresult.IsSuccess)
            {
                Globals_Server.logError("Write failed: NPC " + rNPC.Key + " to bucket " + rNPC.Bucket);
            }

            return(putNPCresult.IsSuccess);
        }
Beispiel #13
0
        /// <summary>
        /// Writes a Language or Language_Serialised object to the database
        /// </summary>
        /// <returns>bool indicating success</returns>
        /// <param name="gameID">Game (bucket) to write to</param>
        /// <param name="l">Language to write</param>
        /// <param name="ls">Language_Serialised to write</param>
        public static bool DatabaseWrite_Language(string gameID, Language l = null, Language_Serialised ls = null)
        {
            if (l != null)
            {
                // convert Language into Language_Serialised
                ls = DatabaseWrite.Language_serialise(l);
            }

            // write Language_Serialised to database
            var rLanguage         = new RiakObject(gameID, ls.id, ls);
            var putLanguageResult = Globals_Server.rClient.Put(rLanguage);

            if (!putLanguageResult.IsSuccess)
            {
                Globals_Server.logError("Write failed: Language " + rLanguage.Key + " to bucket " + rLanguage.Bucket);
            }

            return(putLanguageResult.IsSuccess);
        }
Beispiel #14
0
 /// <summary>
 /// Respond to ransom demands
 /// </summary>
 /// <param name="paid">Whether or not ransom is to be paid</param>
 /// <returns>Bool indicating success</returns>
 public bool RansomResponse(bool paid, out ProtoMessage error)
 {
     error = null;
     // Check if type is ransom
     if (this.type.Equals("ransom"))
     {
         // Check if already replied
         if (replied)
         {
             // Already replied
             error = new ProtoMessage();
             error.ResponseType = DisplayMessages.RansomRepliedAlready;
             return(false);
         }
         Character       captive = null;
         PlayerCharacter captor;
         PlayerCharacter captiveHeadOfHousehold;
         // Confirm captive is still alive and being held
         foreach (string persona in personae)
         {
             string[] split = persona.Split(new char[] { '|' });
             if (split[1].Equals("Captive"))
             {
                 captive = Globals_Game.getCharFromID(split[0]);
             }
         }
         if (captive == null)
         {
             // Captive does not exist- error
             error = new ProtoMessage();
             error.ResponseType = DisplayMessages.ErrorGenericCharacterUnidentified;
             Globals_Server.logError("Captive unidentified in JEntry: " + this.jEntryID);
             return(false);
         }
         else if (!captive.isAlive)
         {
             // Captive is dead
             error = new ProtoMessage();
             error.ResponseType = DisplayMessages.RansomCaptiveDead;
             return(false);
         }
         captor = Globals_Game.getCharFromID(captive.captorID) as PlayerCharacter;
         if (captor == null)
         {
             // Captive does not have a captor
             error = new ProtoMessage();
             error.ResponseType = DisplayMessages.NotCaptive;
             return(false);
         }
         captiveHeadOfHousehold = captive.GetPlayerCharacter();
         if (captiveHeadOfHousehold == null)
         {
             // Captive is not an employee, family member or player character
             Globals_Server.logError("Captive has no PlayerCharacter: " + captive.charID);
             error = new ProtoMessage();
             error.ResponseType = DisplayMessages.ErrorGenericCharacterUnidentified;
             return(false);
         }
         if (paid)
         {
             // Get ransom amount
             uint ransom = 0;
             if (!UInt32.TryParse(entryDetails.MessageFields[1], out ransom))
             {
                 // Error parsing to int
                 Globals_Server.logError("Could not parse ransom to uint in JEntry: " + jEntryID);
                 error = new ProtoMessage();
                 error.ResponseType = DisplayMessages.ErrorGenericMessageInvalid;
                 return(false);
             }
             else
             {
                 // Check captive's head of household has the funds to release
                 if (captiveHeadOfHousehold.GetHomeFief().GetAvailableTreasury(false) >= ransom)
                 {
                     if (!captiveHeadOfHousehold.GetHomeFief().TreasuryTransfer(captor.GetHomeFief(), (Int32)ransom, out error))
                     {
                         return(false);
                     }
                     else
                     {
                         // Release captive
                         captor.ReleaseCaptive(captive);
                         replied = true;
                         Globals_Game.UpdatePlayer(captor.playerID, DisplayMessages.RansomPaid, new string[] { captive.firstName + " " + captive.familyName });
                         return(true);
                     }
                 }
                 else
                 {
                     // Insufficient funds
                     error = new ProtoMessage();
                     error.ResponseType = DisplayMessages.ErrorGenericInsufficientFunds;
                     return(false);
                 }
             }
         }
         // If not paying ransom, inform captor
         else
         {
             // Create journal entry and update captor
             string[]     newPersonae   = new string[] { captive.charID + "|Captive", captor.charID + "|Captor", captiveHeadOfHousehold.charID + "|HeadOfCaptiveFamily" };
             ProtoMessage deniedMessage = new ProtoMessage();
             deniedMessage.ResponseType  = DisplayMessages.RansonDenied;
             deniedMessage.MessageFields = new string[] { captive.firstName + " " + captive.familyName, captor.firstName + " " + captor.familyName, captiveHeadOfHousehold.firstName + " " + captiveHeadOfHousehold.familyName };
             Globals_Game.UpdatePlayer(captor.playerID, deniedMessage);
             JournalEntry ransomDenied = new JournalEntry(Globals_Game.GetNextJournalEntryID(), Globals_Game.clock.currentYear, Globals_Game.clock.currentSeason, newPersonae, "ransomDenied", deniedMessage);
             Globals_Game.AddPastEvent(ransomDenied);
             replied = true;
             return(true);
         }
     }
     else
     {
         // Not a ransom
         error = new ProtoMessage();
         error.ResponseType = DisplayMessages.EntryNotRansom;
         return(false);
     }
 }
            public void read()
            {
                while (client.Status == NetPeerStatus.Running && !ctSource.Token.IsCancellationRequested)
                {
                    WaitHandle.WaitAny(new WaitHandle[] { client.MessageReceivedEvent, ctSource.Token.WaitHandle });
                    NetIncomingMessage im;
                    while ((im = client.ReadMessage()) != null && !ctSource.IsCancellationRequested)
                    {
                        switch (im.MessageType)
                        {
                        case NetIncomingMessageType.DebugMessage:
                        case NetIncomingMessageType.ErrorMessage:
                        case NetIncomingMessageType.WarningMessage:
                        case NetIncomingMessageType.VerboseDebugMessage:
                        case NetIncomingMessageType.Data:
                            try
                            {
                                if (alg != null)
                                {
                                    im.Decrypt(alg);
                                }
                                MemoryStream ms = new MemoryStream(im.Data);
                                ProtoMessage m  = null;
                                try
                                {
                                    m = Serializer.DeserializeWithLengthPrefix <ProtoMessage>(ms, PrefixStyle.Fixed32);
                                }
                                catch (Exception e)
                                {
                                    // Attempt to read string and add to message queue
                                    string s = im.ReadString();
                                    if (!string.IsNullOrWhiteSpace(s))
                                    {
                                        Console.WriteLine("CLIENT: Got message: " + s);

                                        tClient.stringMessageQueue.Enqueue(s);
                                    }
                                }
                                if (m != null)
                                {
                                    Console.WriteLine("CLIENT: Got ProtoMessage with ActionType: " + m.ActionType + " and response type: " + m.ResponseType);
                                    if (m.ResponseType == DisplayMessages.LogInSuccess)
                                    {
                                        loggedIn = true;
                                        tClient.protobufMessageQueue.Enqueue(m);
                                    }
                                    else
                                    {
                                        if (m.ActionType == Actions.Update)
                                        {
                                            // Don't do anything at the moment for updates
                                        }
                                        else
                                        {
                                            tClient.protobufMessageQueue.Enqueue(m);
                                            if (m.ActionType == Actions.LogIn && m.ResponseType == DisplayMessages.None)
                                            {
                                                byte[] key = null;
                                                if (ValidateCertificateAndCreateKey(m as ProtoLogIn, out key))
                                                {
                                                    ComputeAndSendHashAndKey(m as ProtoLogIn, key);
                                                }
                                            }
                                            else
                                            {
                                                // Attempt to read string and add to message queue
                                                string s = im.ReadString();
                                                if (!string.IsNullOrWhiteSpace(s))
                                                {
                                                    tClient.stringMessageQueue.Enqueue(s);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Globals_Server.logError("Error in reading data: " + e.GetType() + " :" + e.Message + "; Stack Trace: " + e.StackTrace);
                            }
                            break;

                        case NetIncomingMessageType.StatusChanged:

                            NetConnectionStatus status = (NetConnectionStatus)im.ReadByte();
                            Console.WriteLine("CLIENT: Status changed to " + status.ToString());
                            //MemoryStream ms2 = new MemoryStream(im.SenderConnection.RemoteHailMessage.Data);
                            if (status == NetConnectionStatus.Connected)
                            {
                                if (im.SenderConnection.RemoteHailMessage != null)
                                {
                                    try
                                    {
                                        MemoryStream ms2 = new MemoryStream(im.SenderConnection.RemoteHailMessage.Data);
                                        ProtoMessage m   = Serializer.DeserializeWithLengthPrefix <ProtoMessage>(ms2, PrefixStyle.Fixed32);
                                        if (m != null)
                                        {
                                            tClient.protobufMessageQueue.Enqueue(m);
                                            if (m.ActionType == Actions.LogIn && m.ResponseType == DisplayMessages.None)
                                            {
                                                byte[] key = null;
                                                if (ValidateCertificateAndCreateKey(m as ProtoLogIn, out key))
                                                {
                                                    if (autoLogIn)
                                                    {
                                                        ComputeAndSendHashAndKey(m as ProtoLogIn, key);
                                                    }
                                                }
                                                else
                                                {
                                                    Console.WriteLine("Certificate validation failed: Server may be untrusted");
                                                    client.Disconnect("Invalid Certificate");
                                                }
                                            }
                                        }
                                    }
                                    catch (Exception e)
                                    {
                                    }
                                }
                                break;
                            }
                            else if (status == NetConnectionStatus.Disconnected)
                            {
                                string reason = im.ReadString();
                                if (!string.IsNullOrEmpty(reason))
                                {
                                    tClient.stringMessageQueue.Enqueue(reason);
                                }
                            }
                            if (im.SenderConnection.RemoteHailMessage != null && (NetConnectionStatus)im.ReadByte() == NetConnectionStatus.Connected)
                            {
                            }
                            break;

                        case NetIncomingMessageType.ConnectionLatencyUpdated:
                            break;

                        default:
                            break;
                        }
                        client.Recycle(im);
                    }
                }
#if DEBUG
                Globals_Server.logEvent("Client listening thread ends");
#endif
            }
Beispiel #16
0
        public void Listen()
        {
            while (server.Status == NetPeerStatus.Running && !ctSource.Token.IsCancellationRequested)
            {
                NetIncomingMessage im;
                WaitHandle.WaitAny(new WaitHandle[] { server.MessageReceivedEvent, ctSource.Token.WaitHandle });
                while ((im = server.ReadMessage()) != null && !ctSource.Token.IsCancellationRequested)
                {
                    if (im.SenderConnection != null)
                    {
                        Globals_Server.logEvent("Recieved: " + im.MessageType.ToString() + " | " + im.SenderConnection.RemoteEndPoint.ToString());
                    }
                    else
                    {
                        Globals_Server.logEvent("Recieved: " + im.MessageType.ToString() + " | NULL");
                    }

                    switch (im.MessageType)
                    {
                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.ErrorMessage:
                    case NetIncomingMessageType.WarningMessage:
                        Globals_Server.logError("Recieved warning message: " + im.ReadString());
                        break;

                    case NetIncomingMessageType.VerboseDebugMessage:
                    case NetIncomingMessageType.Data:
                    {
#if DEBUG
                        //Console.WriteLine("SERVER: recieved data message");
#endif
                        if (!clientConnections.ContainsKey(im.SenderConnection))
                        {
                            //error
                            im.SenderConnection.Disconnect("Not recognised");
                            return;
                        }
                        Client c = clientConnections[im.SenderConnection];
                        if (c.alg != null)
                        {
                            im.Decrypt(c.alg);
                        }
                        ProtoMessage m = null;
                        using (MemoryStream ms = new MemoryStream(im.Data))
                        {
                            try
                            {
                                m = Serializer.DeserializeWithLengthPrefix <ProtoMessage>(ms, PrefixStyle.Fixed32);
                            }
                            catch (Exception e)
                            {
                                NetOutgoingMessage errorMessage = server.CreateMessage(
                                    "Failed to deserialise message. The message may be incorrect, or the decryption may have failed.");
                                if (c.alg != null)
                                {
                                    errorMessage.Encrypt(c.alg);
                                }
                                server.SendMessage(errorMessage, im.SenderConnection,
                                                   NetDeliveryMethod.ReliableOrdered);
                                Globals_Server.logError("Failed to deserialize message for client: " + c.username);
                            }
                        }
                        if (m == null)
                        {
                            string error = "Recieved null message from " + im.SenderEndPoint.ToString();
                            if (clientConnections.ContainsKey(im.SenderConnection))
                            {
                                error += ", recognised client " + clientConnections[im.SenderConnection];
                            }
                            else
                            {
                                error += ", unrecognised client (possible ping)";
                            }
                            error += ". Data: " + im.ReadString();
                            Globals_Server.logError(error);
                            break;
                        }

                        if (m.ActionType == Actions.LogIn)
                        {
                            ProtoLogIn login = m as ProtoLogIn;
                            if (login == null)
                            {
                                im.SenderConnection.Disconnect("Received blank login message.");
                                return;
                            }
                            lock (ServerLock)
                            {
                                if (LogInManager.VerifyUser(c.username, login.userSalt))
                                {
                                    if (LogInManager.ProcessLogIn(login, c))
                                    {
                                        string log = c.username + " logs in from " + im.SenderEndPoint.ToString();
                                        Globals_Server.logEvent(log);
                                    }
                                }
                                else
                                {
                                    ProtoMessage reply = new ProtoMessage
                                    {
                                        ActionType   = Actions.LogIn,
                                        ResponseType = DisplayMessages.LogInFail
                                    };
                                    Server.SendViaProto(reply, c.conn, c.alg);
                                    //reply = new ProtoMessage {
                                    //    ActionType = Actions.Update,
                                    //    ResponseType = DisplayMessages.Error
                                    //};
                                    //Server.SendViaProto(reply, c.conn, c.alg);
                                    im.SenderConnection.Disconnect("Authentication Fail");
                                    Globals_Server.logEvent("Wrong Password, disconnecting user.");
                                }
                            }
                        }
                        // temp for testing, should validate connection first
                        else if (clientConnections.ContainsKey(im.SenderConnection))
                        {
                            if (Globals_Game.IsObserver(c))
                            {
                                ProcessMessage(m, im.SenderConnection);
                                ProtoClient clientDetails = new ProtoClient(c);
                                clientDetails.ActionType   = Actions.Update;
                                clientDetails.ResponseType = DisplayMessages.Success;
                                SendViaProto(clientDetails, im.SenderConnection, c.alg);
                            }
                            else
                            {
                                im.SenderConnection.Disconnect("Not logged in- Disconnecting");
                            }
                        }
                    }
                    break;

                    case NetIncomingMessageType.StatusChanged:
                        byte stat = im.ReadByte();
                        NetConnectionStatus status = NetConnectionStatus.None;
                        if (Enum.IsDefined(typeof(NetConnectionStatus), Convert.ToInt32(stat)))
                        {
                            status = (NetConnectionStatus)stat;
                        }
                        else
                        {
                            Globals_Server.logError("Failure to parse byte " + stat + " to NetConnectionStatus for endpoint " + im.ReadIPEndPoint());
                        }
                        Globals_Server.logEvent("\tStatus is now: " + status);
                        if (status == NetConnectionStatus.Disconnected)
                        {
                            string reason = im.ReadString();
                            if (reason == null)
                            {
                                reason = "Unknown";
                            }
                            Globals_Server.logEvent(im.SenderConnection.RemoteEndPoint.ToString() + " has disconnected. Reason: " + reason);
                            if (clientConnections.ContainsKey(im.SenderConnection))
                            {
                                Disconnect(im.SenderConnection);
                            }
                        }
                        break;

                    case NetIncomingMessageType.ConnectionApproval:
                    {
                        string senderID = im.ReadString();
                        string text     = im.ReadString();
                        Client client;
                        Globals_Server.Clients.TryGetValue(senderID, out client);
                        if (client != null)
                        {
                            ProtoLogIn logIn;
                            //ProtoMessage logIn;
                            if (!LogInManager.AcceptConnection(client, text, out logIn))
                            {
                                im.SenderConnection.Deny("User not recognised.");
                            }
                            else
                            {
                                ProtoMessage temp = logIn;

                                NetOutgoingMessage msg = server.CreateMessage();
                                MemoryStream       ms  = new MemoryStream();
                                // Include X509 certificate as bytes for client to validate
                                //Serializer.SerializeWithLengthPrefix<ProtoLogIn>(ms, logIn, PrefixStyle.Fixed32);
                                Serializer.SerializeWithLengthPrefix <ProtoMessage>(ms, temp, PrefixStyle.Fixed32);
                                msg.Write(ms.GetBuffer());

                                clientConnections.Add(im.SenderConnection, client);
                                client.conn = im.SenderConnection;
                                im.SenderConnection.Approve(msg);
                                //server.FlushSendQueue();
                                Globals_Server.logEvent("Accepted connection from " + client.username + " | " + senderID + " | " + text);
                            }
                        }
                        else
                        {
                            im.SenderConnection.Deny("Username unrecognised.");
                        }
                        server.FlushSendQueue();
                    }

                    break;

                    case NetIncomingMessageType.ConnectionLatencyUpdated:
                        Globals_Server.logEvent("LATENCY: Still getting these.");
                        break;

                    default:
                        Globals_Server.logError("Received unrecognised incoming message type: " + im.MessageType);
                        break;
                    }
                    server.Recycle(im);
                }
            }
            Globals_Server.logEvent("Server listening thread exits.");
        }