Webブラウザゲームに参加してデータを収集し、禁止された人々を蹴るある種のボットをC#で作成しようとしています。私のデータを MySQL データベースに送信して、人々が Web サイトでデータを検索できるようにしています。
何が起こっているのかをよりよく説明するために、コードをできるだけ単純化しようとしました。
ゲーム内で人によって何かが発生したときに呼び出される 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 を取得しています。このコードは、Player オブジェクトが関数内の MySQL データで作成されるのを待たずにすぐに呼び出されますか? - 関数は同時に呼び出すことができ、MySQL コマンドを同時に作成します。- すべての MySQL クエリを処理したい。スキップする必要はありません。
それで、新しい MySQL クエリが処理される前に待機する非同期またはロックを考えていますか?
私は C# の学習を始めたばかりで、この部分を解決する方法が少し難しいと感じています。誰かがこれらを解決する方法を教えてもらえますか? または、何を探すべきかについてのヒントを教えてください。
前もって感謝します!