コード例 #1
0
        private static IEnumerator UpdateLogin(byte[] hash)
        {
            var updateLogged = new SQLiteCommand("INSERT OR REPLACE INTO loggedin (hash, time) VALUES (@hash, @time);", Connection);

            updateLogged.Parameters.AddWithValue("@time", FormatDate(DateTime.Now + TimeSpan.FromHours(6)));
            updateLogged.Parameters.AddWithValue("@hash", hash);

            yield return(Async.Detach());

            lock (Connection)
            {
                updateLogged.ExecuteNonQuery();
            }
        }
コード例 #2
0
        internal static bool TryRegister(Entity ent, string password, Action onFinish)
        {
            var exists = ConnectedPlayers[ent.EntRef] != null;

            if (!exists)
            {
                IEnumerator routine()
                {
                    var hwid = ent.HWID;

                    byte[] bytes = Sha256(password);

                    var command = new SQLiteCommand("INSERT INTO players (hwid, password, data) VALUES (@hwid, @password, @data);", Connection);

                    command.Parameters.AddWithValue("@hwid", hwid);
                    command.Parameters.AddWithValue("@password", bytes);
                    command.Parameters.AddWithValue("@data", "{}");

                    yield return(Async.Detach());

                    lock (Connection)
                    {
                        command.ExecuteNonQuery();
                    }

                    yield return(Async.Attach());

                    Log.Info($"Registered HWID {hwid} inside database");

                    ConnectedPlayers[ent.EntRef] = new PlayerInfo
                    {
                        HWID         = hwid,
                        PasswordHash = bytes,
                        Data         = new Dictionary <string, string>(),
                        LoggedIn     = true,
                    };

                    onFinish();

                    yield return(UpdateLogin(GetLoginHash(ent)));
                }

                Async.Start(routine());
            }

            return(!exists);
        }
コード例 #3
0
            public void UpdateDataAsync(Action <int> action = null)
            {
                IEnumerator routine()
                {
                    var cmd = new SQLiteCommand("UPDATE players SET data = @data WHERE hwid = @hwid", Connection);

                    cmd.Parameters.AddWithValue("@data", JsonConvert.SerializeObject(Data));
                    cmd.Parameters.AddWithValue("@hwid", HWID);

                    yield return(Async.Detach());

                    lock (Connection)
                    {
                        cmd.ExecuteNonQuery();
                    }
                }

                Async.Start(routine());
            }
コード例 #4
0
        private static void Init()
        {
            Script.PlayerConnected.Add((sender, player) =>
            {
                IEnumerator routine()
                {
                    var cmd = new SQLiteCommand($"SELECT * FROM players WHERE hwid = @value;", Connection);

                    cmd.Parameters.AddWithValue("@value", player.HWID);

                    yield return(Async.Detach());

                    PlayerInfo found;
                    lock (Connection)
                    {
                        var reader = cmd.ExecuteReader();
                        found      = PlayerInfo.Get(reader);

                        reader.Close();
                    }

                    yield return(Async.Attach());

                    ConnectedPlayers[player.EntRef] = found;

                    if (found != null)
                    {
                        Log.Debug($"Found entry for player {player.Name}");
                    }
                    else
                    {
                        Log.Debug($"Did not find entry for player {player.Name}");
                    }

                    if (found != null)
                    {
                        var hash = GetLoginHash(player);

                        var findLogged = new SQLiteCommand("SELECT * FROM loggedin WHERE hash = @hash AND (datetime(time) > datetime('now', 'localtime'));", Connection);

                        findLogged.Parameters.AddWithValue("@hash", hash);

                        yield return(Async.Detach());

                        bool logged;
                        lock (Connection)
                        {
                            logged = findLogged.ExecuteScalar() != null;
                        }

                        yield return(Async.Attach());

                        if (logged)
                        {
                            ConnectedPlayers[player.EntRef].LoggedIn = true;

                            player.Tell("%iYou have logged in automatically.");
                            Log.Info($"Player {player.Name} automatically logged in.");

                            PlayerLoggedIn.Run(null, player);

                            yield return(UpdateLogin(hash));
                        }
                    }
                }

                Async.Start(routine());
            }, int.MinValue);

            Script.PlayerDisconnected.Add((sender, player) =>
            {
                if (player.IsLogged())
                {
                    PlayerLoggedOut.Run(null, player);
                }

                ConnectedPlayers[player.EntRef]?.UpdateDataAsync(delegate
                {
                    ConnectedPlayers[player.EntRef] = null;
                });
            }, int.MaxValue);

            #region Commands
            // REGISTER
            Command.TryRegister(Parse.SmartParse.CreateCommand(
                                    name: "register",
                                    argTypes: new[] { Parse.SmartParse.String, Parse.SmartParse.String },
                                    action : delegate(Entity sender, object[] args)
            {
                var pw           = args[0] as string;
                var confirmation = args[1] as string;

                if (pw != confirmation)
                {
                    sender.Tell("%ePasswords do not match.");
                    return;
                }

                if (!TryRegister(sender, pw, () =>
                {
                    sender.Tell("%iYou have successfully registered.");

                    ConnectedPlayers[sender.EntRef].LoggedIn = true;
                }))
                {
                    sender.Tell("%eYou are already registered. Login instead.");
                    return;
                }
            },
                                    usage: "!register <password> <confirm>",
                                    description: "Register to the server's database"));

            // LOGIN
            Command.TryRegister(Parse.SmartParse.CreateCommand(
                                    name: "login",
                                    argTypes: new[] { Parse.SmartParse.String },
                                    action : delegate(Entity sender, object[] args)
            {
                var pw = args[0] as string;

                if (sender.TryGetInfo(out var row))
                {
                    if (row.LoggedIn)
                    {
                        sender.Tell("%eYou are already logged in.");
                        return;
                    }

                    if (!ByteArrayEquals(row.PasswordHash, Sha256(pw)))
                    {
                        sender.Tell("%eIncorrect password!");
                        return;
                    }

                    row.LoggedIn = true;

                    Async.Start(UpdateLogin(GetLoginHash(sender)));

                    PlayerLoggedIn.Run(null, sender);

                    sender.Tell("%iYou have logged in.");
                    return;
                }

                sender.Tell("%eYou are not registered!");
                return;
            },
                                    usage: "!login <password>",
                                    description: "Logs you into the server database"));

            // LOGOUT
            Command.TryRegister(Parse.SmartParse.CreateCommand(
                                    name : "logout",
                                    argTypes : new Parse.IArgParse[0],
                                    action : delegate(Entity sender, object[] args)
            {
                if (sender.TryGetInfo(out var row))
                {
                    if (!row.LoggedIn)
                    {
                        sender.Tell("%eYou aren't logged in.");
                        return;
                    }

                    row.LoggedIn = false;

                    IEnumerator routine()
                    {
                        var cmd = new SQLiteCommand("DELETE FROM loggedin WHERE hash = @hash;", Connection);

                        cmd.Parameters.AddWithValue("@hash", GetLoginHash(sender));

                        yield return(Async.Detach());

                        lock (Connection)
                        {
                            cmd.ExecuteNonQuery();
                        }
                    }

                    Async.Start(routine());

                    PlayerLoggedOut.Run(null, sender);

                    sender.Tell("%iYou have logged out.");
                    return;
                }
            },
                                    usage: "!logout",
                                    description: "Logs you out of the server database"));

            // CHANGEPASSWORD
            Command.TryRegister(Parse.SmartParse.CreateCommand(
                                    name: "changepassword",
                                    argTypes: new[] { Parse.SmartParse.String, Parse.SmartParse.String },
                                    action : delegate(Entity sender, object[] args)
            {
                var pw           = args[0] as string;
                var confirmation = args[1] as string;

                if (sender.TryGetInfo(out var row) && row.LoggedIn)
                {
                    if (pw != confirmation)
                    {
                        sender.Tell("%ePasswords do not match.");
                        return;
                    }

                    IEnumerator routine()
                    {
                        var hash = Sha256(pw);
                        var cmd  = new SQLiteCommand("UPDATE players SET password = @hash WHERE hwid = @value;", Connection);

                        cmd.Parameters.AddWithValue("@value", sender.HWID);
                        cmd.Parameters.AddWithValue("@hash", hash);

                        yield return(Async.Detach());

                        int status;
                        lock (Connection)
                        {
                            status = cmd.ExecuteNonQuery();
                        }

                        yield return(Async.Attach());

                        if (status == -1)
                        {
                            sender.Tell($"%eError changing password: {status}");
                            yield break;
                        }

                        row.PasswordHash = hash;
                        sender.Tell("%iPassword changed successfully.");
                    }

                    Async.Start(routine());
                }