2

我正在尝试在 C# 中创建某种机器人来加入网络浏览器游戏并收集数据并踢被禁止的人。我将我的数据发送到 MySQL 数据库,以便人们可以在网站上查找他们的数据。

我试图尽可能地简化我的代码,以更好地解释发生了什么。

我有一个 eventHandler ,当一个人在游戏中发生某些事情时会调用它,所以我相信它可以在同一时间被调用。

//EventHandler
public static void OnMessage(object sender, InOutPlayerc.Message m)
{
    int id = m.getInt(0);

    switch (m.Type)
    {
        //If a player logged in (m = [id, name])
        case "login":
            Player p = loadPlayerSQL(m.getString(1));
            if(p.Status == "BANNED") {
                kickPlayer(p);
            }
            else {
                //Store the player local, this way 
                savePlayerLocal(id, p);
            }
            return;

        //If a player said something (m = [id, chatmessage])
        case "talk":
            addTimesTalked(loadPlayerLocal(id));
            return;

        //If a player logs out (m = [id])
        case "logout":
            savePlayerSQL(loadPlayerLocal(id));
            return;
    }
}

因为 InOutPlayerc.Message m 只包含不同 InOutPlayerc.Message.Type 的 id,所以我必须将播放器存储在本地。所以我可以通过提供 id 来取回 Player 对象。

public static void savePlayerLocal(int id, Player p){...};
public static Player loadPlayerLocal(int id){...};

这是我的其余功能:

public static Player loadPlayerSQL(string username)
{
    try
    {
        int timessaid;
        string status;
        using (MySqlCommand cmd = DB.CreateCommand())
        {
            cmd.CommandText = "SELECT * FROM Players WHERE Username = @Username";
            cmd.Parameters.AddWithValue("@Username", username);
            using (MySqlDataReader reader = cmd.ExecuteReader())
            {
                reader.Read();
                timessaid = Convert.ToInt32(reader["Chat"]);
                status = reader["Status"].ToString();
            }
        }
        return new Player(username, status, timessaid);
    }
    catch (Exception e)
    {
        return new Player(username, "DEFAULT", 0);
    }
}

public static void addTimesTalked(Player p)
{
    try
    {
        using (MySqlCommand cmd = DB.CreateCommand())
        {
            p.Chat = p.Chat + 1;
            cmd.CommandText = "UPDATE Players SET Chat = @Chat WHERE Username = @Username";
            cmd.Parameters.AddWithValue("@Username", p.Username);
            cmd.Parameters.AddWithValue("@Chat", p.Chat);
            cmd.ExecuteNonQuery();
        }
    }
    catch (Exception e)
    {
    }
}

public static void savePlayerSQL(Player p)
{
    try
    {
        using (MySqlCommand cmd = DB.CreateCommand())
        {
            cmd.CommandText = "UPDATE Players SET Status = @Status, Chat = @Chat WHERE Username = @Username";
            cmd.Parameters.AddWithValue("@Username", p.Username);
            cmd.Parameters.AddWithValue("@Status", p.Status);
            cmd.Parameters.AddWithValue("@Chat", p.Chat);
            cmd.ExecuteNonQuery();
        }
    }
    catch (Exception e)
    {
    }
}

现在这是我的问题: - 我在 'if(p.Status == "BANNED") {' 处收到 System.NullReferenceException。这段代码是不是在函数中没有等待之前用 MySQL 数据创建 Player 对象的情况下立即调用?- 可以同时调用函数,同时创建 MySQL 命令。- 我希望处理所有 MySQL 查询。没有一个应该被跳过。

所以我在想一些异步的东西,或者在处理新的 MySQL 查询之前等待的锁?

我刚刚开始学习 C#,我发现这部分有点难以解决。有人可以帮我解决这些问题吗?或者甚至暗示我应该寻找什么?

先感谢您!

4

1 回答 1

0

如果 id 和 username 不一样,那就是你的问题。您在 loadPlayerSQL(string username) 中的 SQL 将找不到您的用户,因为您传递的是 id 而不是用户名。

于 2012-09-16T01:48:07.893 回答