Exemplo n.º 1
0
 internal PlayerStateEvent(EventMessages msg, PlayerPayLoad ppl, bool on) : base(msg)
 {
     Player = ppl;
     Online = on;
 }
Exemplo n.º 2
0
        /// <summary>
        ///     Will compare the last status with the current one and return event updates.
        /// </summary>
        /// <returns></returns>
        public EventBase[] Update()
        {
            // event-queue
            var events  = new List <EventBase>();
            var isFirst = last == null;
            var current = Base.GetLatestServerInfo();

            if (current != null)
            {
                // if first info, or last success was different from this (either went online or went offline) => invoke
                if (NotifyServer && (isFirst || last.HadSuccess != current.HadSuccess))
                {
                    Debug.WriteLine("Server '" + Base.Address + ":" + Base.Port + "' status change: " + current.HadSuccess);
                    var errMsg = current.LastError != null ? "Connection Failed: " + current.LastError.GetType().Name : "";
                    events.Add(new OnlineStatusEvent(current.HadSuccess, current.HadSuccess ? current.ServerMotd : errMsg));
                }

                // if first info, or last player count was different (player went online or offline) => invoke
                if (NotifyCount)
                {
                    var diff = isFirst
                        ? current.CurrentPlayerCount
                        : current.CurrentPlayerCount - last.CurrentPlayerCount;
                    if (diff != 0)
                    {
                        Debug.WriteLine("Server '" + Base.Address + ":" + Base.Port + "' count change: " + diff);
                        events.Add(new PlayerChangeEvent(diff));
                    }
                }

                // check current list for new players
                var onlineIds = new List <string>();
                if (current.OnlinePlayers != null)
                {
                    foreach (var p in current.OnlinePlayers)
                    {
                        // save online user id temporarily
                        if (!onlineIds.Contains(p.Id))
                        {
                            onlineIds.Add(p.Id);
                        }
                        // register name
                        userNames[p.Id] = p.Name;
                        // if notify and user has state and last state was offline and user is watched, notify change
                        if (NotifyNames && (!userStates.ContainsKey(p.Id) || !userStates[p.Id]))
                        {
                            events.Add(new PlayerStateEvent(p, true));
                        }
                        // register state or set to true
                        userStates[p.Id] = true;
                    }
                }

                // this needs to be done to avoid ElementChangedException
                var keys = userStates.Keys.ToArray();
                // check all states for players who went offline
                foreach (var k in keys)
                {
                    if (!userStates[k] || onlineIds.Contains(k))
                    {
                        continue;
                    }
                    // if user state still true, but he is not in online list => went offline
                    userStates[k] = false;
                    // create payload
                    var p = new PlayerPayLoad {
                        Id = k, RawName = userNames[k]
                    };
                    // notify => invoke
                    if (NotifyNames)
                    {
                        events.Add(new PlayerStateEvent(p, false));
                    }
                }
            }
            // set new last
            last = current;
            ApplyServerInfo(current);
            return(events.ToArray());
        }
Exemplo n.º 3
0
        protected override async Task <ServerInfoBase> Get(CancellationToken ct, DateTime startPing, Stopwatch pingTime, TcpClient client, NetworkStream stream)
        {
            var _offset     = 0;
            var writeBuffer = new List <byte>();

            WriteVarInt(writeBuffer, Proto);
            WriteString(writeBuffer, address);
            WriteShort(writeBuffer, Convert.ToInt16(port));
            WriteVarInt(writeBuffer, 1);
            Flush(ct, writeBuffer, stream, 0);
            // yep, twice.
            Flush(ct, writeBuffer, stream, 0);

            var readBuffer = new byte[BufferSize];
            await stream.ReadAsync(readBuffer, 0, readBuffer.Length, ct);

            // done
            stream.Close();
            client.Close();
            // IF an IOException arises here, thie server is probably not a minecraft-one
            var length     = ReadVarInt(ref _offset, readBuffer);
            var packet     = ReadVarInt(ref _offset, readBuffer);
            var jsonLength = ReadVarInt(ref _offset, readBuffer);
            var json       = ReadString(ref _offset, readBuffer, jsonLength);

            dynamic ping = JsonConvert.DeserializeObject(json);

            var sample = new List <PlayerPayLoad>();

            if (json.Contains("\"sample\":["))
            {
                try
                {
                    foreach (dynamic key in ping.players.sample)
                    {
                        if (key.id == null || key.name == null)
                        {
                            continue;
                        }
                        var plr = new PlayerPayLoad()
                        {
                            Id = key.id, RawName = key.name
                        };
                        sample.Add(plr);
                    }
                }
                catch (Exception e)
                {
                    Program.WriteLine("Error when sample processing: " + e.ToString());
                }
            }

            var desc = "";

            if (json.Contains("\"description\":{\""))
            {
                try
                {
                    desc = (string)ping.description.text;
                }
                catch (Exception e)
                {
                    Program.WriteLine("Error description text: " + e.ToString());
                }
            }
            if (string.IsNullOrEmpty(desc))
            {
                try
                {
                    desc = (string)ping.description;
                }
                catch (Exception ex)
                {
                    Program.WriteLine("Error description text: " + ex.ToString());
                }
            }

            if (string.IsNullOrEmpty(desc))
            {
                throw new FormatException("Empty description!");
            }

            return(new ServerInfoBase(startPing, pingTime.ElapsedMilliseconds, desc, (int)ping.players.max, (int)ping.players.online, (string)ping.version.name, sample));
        }
Exemplo n.º 4
0
        protected override async Task <ServerInfoBase> Get(CancellationToken ct, DateTime startPing, Stopwatch pingTime, TcpClient client, NetworkStream stream)
        {
            var _offset     = 0;
            var writeBuffer = new List <byte>();

            WriteVarInt(writeBuffer, Proto);
            WriteString(writeBuffer, address);
            WriteShort(writeBuffer, Convert.ToInt16(port));
            WriteVarInt(writeBuffer, 1);
            Flush(ct, writeBuffer, stream, 0);
            // yep, twice.
            Flush(ct, writeBuffer, stream, 0);

            var readBuffer = new byte[BufferSize];
            await stream.ReadAsync(readBuffer, 0, readBuffer.Length, ct);

            // done
            stream.Close();
            client.Close();
            // IF an IOException arises here, thie server is probably not a minecraft-one
            var length     = ReadVarInt(ref _offset, readBuffer);
            var packet     = ReadVarInt(ref _offset, readBuffer);
            var jsonLength = ReadVarInt(ref _offset, readBuffer);
            var json       = ReadString(ref _offset, readBuffer, jsonLength);

            dynamic ping = JsonConvert.DeserializeObject(json);

            // parse player sample
            var sample = new List <PlayerPayLoad>();

            if (json.Contains("\"sample\":["))
            {
                try
                {
                    foreach (dynamic key in ping.players.sample)
                    {
                        if (key.id == null || key.name == null)
                        {
                            continue;
                        }
                        var plr = new PlayerPayLoad()
                        {
                            Id = key.id, RawName = key.name
                        };
                        sample.Add(plr);
                    }
                }
                catch (Exception e)
                {
                    Logger.WriteLine("Error when sample processing: " + e.ToString(), Types.LogLevel.Debug);
                }
            }
            // parse favicon
            Bitmap image = null;

            if (json.Contains("\"favicon\":\""))
            {
                try
                {
                    var hdr    = "data:image/png;base64,";
                    var imgStr = (string)ping.favicon;
                    if (!imgStr.StartsWith(hdr))
                    {
                        throw new Exception("Unkown Format");
                    }
                    byte[] imgData = Convert.FromBase64String(imgStr.Substring(hdr.Length));
                    using (var imgStream = new MemoryStream(imgData, 0, imgData.Length))
                        image = new Bitmap(imgStream);
                }
                catch (Exception ie)
                {
                    Logger.WriteLine("Error parsing favicon: " + ie.ToString(), Types.LogLevel.Debug);
                }
            }
            // parse MOTD/description
            var desc = "";

            if (json.Contains("\"description\":{\""))
            {
                try
                {
                    desc = (string)ping.description.text;
                }
                catch (Exception e)
                {
                    Logger.WriteLine("Error description.text: " + e.ToString(), Types.LogLevel.Debug);
                }
            }
            if (string.IsNullOrEmpty(desc))
            {
                try
                {
                    desc = (string)ping.description;
                }
                catch (Exception ex)
                {
                    Logger.WriteLine("Error description: " + ex.ToString(), Types.LogLevel.Debug);
                }
            }

            if (string.IsNullOrEmpty(desc))
            {
                throw new FormatException("Empty description!");
            }

            return(new ServerInfoBase(startPing, pingTime.ElapsedMilliseconds, desc, (int)ping.players.max, (int)ping.players.online, (string)ping.version.name, image, sample));
        }
Exemplo n.º 5
0
 public PlayerStateEvent(PlayerPayLoad ppl, bool on)
 {
     Player = ppl;
     Online = on;
 }