-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDataStore.cs
More file actions
313 lines (281 loc) · 13.7 KB
/
Copy pathDataStore.cs
File metadata and controls
313 lines (281 loc) · 13.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using MySql.Data.MySqlClient;
using Newtonsoft.Json;
using TShockAPI;
namespace PlayerMail
{
public interface IDataStore : IDisposable
{
PlayerMailData GetPlayerData(string playerName);
void SetPlayerData(string playerName, PlayerMailData data);
bool RemovePlayerData(string playerName);
Dictionary<string, PlayerMailData> GetAllPlayerData();
void ClearAllPlayerData();
List<InboxMessage> GetInboxForPlayer(string playerName);
void AddInboxMessage(InboxMessage msg);
void MarkInboxRead(string messageId);
bool IsBlacklisted(string playerName);
bool AddBlacklist(string playerName);
bool RemoveBlacklist(string playerName);
List<string> GetBlacklist();
}
public class JsonDataStore : IDataStore
{
private readonly string SaveDir;
private readonly string PlayersPath;
private readonly string InboxPath;
private readonly string BlacklistPath;
private Dictionary<string, PlayerMailData> Players;
private List<InboxMessage> InboxMessages;
private HashSet<string> Blacklist;
public JsonDataStore()
{
SaveDir = Path.Combine(TShock.SavePath, "PlayerMail");
PlayersPath = Path.Combine(SaveDir, "players.json");
InboxPath = Path.Combine(SaveDir, "inbox.json");
BlacklistPath = Path.Combine(SaveDir, "blacklist.json");
LoadAll();
}
private void LoadAll()
{
Directory.CreateDirectory(SaveDir);
if (File.Exists(PlayersPath))
{
var json = File.ReadAllText(PlayersPath);
var raw = JsonConvert.DeserializeObject(json, typeof(Dictionary<string, PlayerMailData>)) as Dictionary<string, PlayerMailData>;
Players = new Dictionary<string, PlayerMailData>(raw ?? new Dictionary<string, PlayerMailData>(), StringComparer.OrdinalIgnoreCase);
}
else Players = new Dictionary<string, PlayerMailData>(StringComparer.OrdinalIgnoreCase);
if (File.Exists(InboxPath))
{
var json = File.ReadAllText(InboxPath);
InboxMessages = JsonConvert.DeserializeObject(json, typeof(List<InboxMessage>)) as List<InboxMessage> ?? new List<InboxMessage>();
}
else InboxMessages = new List<InboxMessage>();
if (File.Exists(BlacklistPath))
{
var json = File.ReadAllText(BlacklistPath);
var list = JsonConvert.DeserializeObject(json, typeof(List<string>)) as List<string> ?? new List<string>();
Blacklist = new HashSet<string>(list, StringComparer.OrdinalIgnoreCase);
}
else Blacklist = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
}
private void SavePlayers() => File.WriteAllText(PlayersPath, JsonConvert.SerializeObject(Players, Formatting.Indented));
private void SaveInbox() => File.WriteAllText(InboxPath, JsonConvert.SerializeObject(InboxMessages, Formatting.Indented));
private void SaveBlacklist() => File.WriteAllText(BlacklistPath, JsonConvert.SerializeObject(Blacklist.ToList(), Formatting.Indented));
public PlayerMailData GetPlayerData(string playerName) => Players.TryGetValue(playerName, out var data) ? data : null;
public void SetPlayerData(string playerName, PlayerMailData data) { Players[playerName] = data; SavePlayers(); }
public bool RemovePlayerData(string playerName) { if (Players.Remove(playerName)) { SavePlayers(); return true; } return false; }
public Dictionary<string, PlayerMailData> GetAllPlayerData() => new Dictionary<string, PlayerMailData>(Players, StringComparer.OrdinalIgnoreCase);
public void ClearAllPlayerData() { Players.Clear(); SavePlayers(); }
public List<InboxMessage> GetInboxForPlayer(string playerName) => InboxMessages.Where(m => m.ToPlayer == playerName).OrderByDescending(m => m.SendTime).ToList();
public void AddInboxMessage(InboxMessage msg) { InboxMessages.Add(msg); SaveInbox(); }
public void MarkInboxRead(string messageId) { var msg = InboxMessages.FirstOrDefault(m => m.Id == messageId); if (msg != null) { msg.IsRead = true; SaveInbox(); } }
public bool IsBlacklisted(string playerName) => Blacklist.Contains(playerName);
public bool AddBlacklist(string playerName) { if (Blacklist.Add(playerName)) { SaveBlacklist(); return true; } return false; }
public bool RemoveBlacklist(string playerName) { if (Blacklist.Remove(playerName)) { SaveBlacklist(); return true; } return false; }
public List<string> GetBlacklist() => Blacklist.ToList();
public void Dispose() { }
}
public class MySqlDataStore : IDataStore
{
private readonly string ConnectionString;
private readonly string ServerId;
public MySqlDataStore(string connectionString)
{
ConnectionString = connectionString;
ServerId = TShock.Config.Settings.ServerName ?? Environment.MachineName;
InitTables();
}
private void InitTables()
{
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = @"
CREATE TABLE IF NOT EXISTS playermail_players (
PlayerName VARCHAR(50) PRIMARY KEY,
Email VARCHAR(100) NOT NULL,
BindTime BIGINT NOT NULL,
ServerId VARCHAR(50),
LastUpdate TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS playermail_inbox (
Id VARCHAR(32) PRIMARY KEY,
FromPlayer VARCHAR(50) NOT NULL,
ToPlayer VARCHAR(50) NOT NULL,
Content TEXT NOT NULL,
SendTime VARCHAR(20) NOT NULL,
IsRead BOOLEAN DEFAULT FALSE,
ServerId VARCHAR(50),
INDEX idx_toPlayer (ToPlayer),
INDEX idx_isRead (IsRead)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS playermail_blacklist (
PlayerName VARCHAR(50) PRIMARY KEY,
AddedBy VARCHAR(50),
AddTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ServerId VARCHAR(50)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
cmd.ExecuteNonQuery();
}
public PlayerMailData GetPlayerData(string playerName)
{
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT Email, BindTime FROM playermail_players WHERE PlayerName = @name";
cmd.Parameters.AddWithValue("@name", playerName);
using var reader = cmd.ExecuteReader();
if (reader.Read())
return new PlayerMailData { Email = reader.GetString("Email"), BindTime = reader.GetInt64("BindTime") };
return null;
}
public void SetPlayerData(string playerName, PlayerMailData data)
{
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = @"
INSERT INTO playermail_players (PlayerName, Email, BindTime, ServerId)
VALUES (@name, @email, @time, @server)
ON DUPLICATE KEY UPDATE Email = @email, BindTime = @time, ServerId = @server";
cmd.Parameters.AddWithValue("@name", playerName);
cmd.Parameters.AddWithValue("@email", data.Email);
cmd.Parameters.AddWithValue("@time", data.BindTime);
cmd.Parameters.AddWithValue("@server", ServerId);
cmd.ExecuteNonQuery();
}
public bool RemovePlayerData(string playerName)
{
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "DELETE FROM playermail_players WHERE PlayerName = @name";
cmd.Parameters.AddWithValue("@name", playerName);
return cmd.ExecuteNonQuery() > 0;
}
public Dictionary<string, PlayerMailData> GetAllPlayerData()
{
var dict = new Dictionary<string, PlayerMailData>(StringComparer.OrdinalIgnoreCase);
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT PlayerName, Email, BindTime FROM playermail_players";
using var reader = cmd.ExecuteReader();
while (reader.Read())
{
var name = reader.GetString("PlayerName");
dict[name] = new PlayerMailData { Email = reader.GetString("Email"), BindTime = reader.GetInt64("BindTime") };
}
return dict;
}
public void ClearAllPlayerData()
{
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "DELETE FROM playermail_players";
cmd.ExecuteNonQuery();
}
public List<InboxMessage> GetInboxForPlayer(string playerName)
{
var list = new List<InboxMessage>();
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM playermail_inbox WHERE ToPlayer = @name ORDER BY SendTime DESC";
cmd.Parameters.AddWithValue("@name", playerName);
using var reader = cmd.ExecuteReader();
while (reader.Read())
{
list.Add(new InboxMessage
{
Id = reader.GetString("Id"),
FromPlayer = reader.GetString("FromPlayer"),
ToPlayer = reader.GetString("ToPlayer"),
Content = reader.GetString("Content"),
SendTime = reader.GetString("SendTime"),
IsRead = reader.GetBoolean("IsRead")
});
}
return list;
}
public void AddInboxMessage(InboxMessage msg)
{
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = @"
INSERT INTO playermail_inbox (Id, FromPlayer, ToPlayer, Content, SendTime, IsRead, ServerId)
VALUES (@id, @from, @to, @content, @time, @read, @server)";
cmd.Parameters.AddWithValue("@id", msg.Id);
cmd.Parameters.AddWithValue("@from", msg.FromPlayer);
cmd.Parameters.AddWithValue("@to", msg.ToPlayer);
cmd.Parameters.AddWithValue("@content", msg.Content);
cmd.Parameters.AddWithValue("@time", msg.SendTime);
cmd.Parameters.AddWithValue("@read", msg.IsRead);
cmd.Parameters.AddWithValue("@server", ServerId);
cmd.ExecuteNonQuery();
}
public void MarkInboxRead(string messageId)
{
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "UPDATE playermail_inbox SET IsRead = TRUE WHERE Id = @id";
cmd.Parameters.AddWithValue("@id", messageId);
cmd.ExecuteNonQuery();
}
public bool IsBlacklisted(string playerName)
{
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT 1 FROM playermail_blacklist WHERE PlayerName = @name";
cmd.Parameters.AddWithValue("@name", playerName);
return cmd.ExecuteScalar() != null;
}
public bool AddBlacklist(string playerName)
{
try
{
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO playermail_blacklist (PlayerName, ServerId) VALUES (@name, @server)";
cmd.Parameters.AddWithValue("@name", playerName);
cmd.Parameters.AddWithValue("@server", ServerId);
cmd.ExecuteNonQuery();
return true;
}
catch { return false; }
}
public bool RemoveBlacklist(string playerName)
{
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "DELETE FROM playermail_blacklist WHERE PlayerName = @name";
cmd.Parameters.AddWithValue("@name", playerName);
return cmd.ExecuteNonQuery() > 0;
}
public List<string> GetBlacklist()
{
var list = new List<string>();
using var conn = new MySqlConnection(ConnectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT PlayerName FROM playermail_blacklist";
using var reader = cmd.ExecuteReader();
while (reader.Read())
list.Add(reader.GetString("PlayerName"));
return list;
}
public void Dispose() { }
}
}