-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathBanStickDatabaseHandler.java
More file actions
422 lines (366 loc) · 14.3 KB
/
BanStickDatabaseHandler.java
File metadata and controls
422 lines (366 loc) · 14.3 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
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
package com.programmerdan.minecraft.banstick.handler;
import com.programmerdan.minecraft.banstick.BanStick;
import com.programmerdan.minecraft.banstick.data.BSBan;
import com.programmerdan.minecraft.banstick.data.BSIP;
import com.programmerdan.minecraft.banstick.data.BSIPData;
import com.programmerdan.minecraft.banstick.data.BSLog;
import com.programmerdan.minecraft.banstick.data.BSPlayer;
import com.programmerdan.minecraft.banstick.data.BSSession;
import com.programmerdan.minecraft.banstick.data.BSShare;
import java.net.InetAddress;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import vg.civcraft.mc.civmodcore.dao.ManagedDatasource;
/**
* Ties into the managed datasource processes of the CivMod core plugin.
*
* @author <a href="mailto:programmerdan@gmail.com">ProgrammerDan</a>
*
*/
public class BanStickDatabaseHandler {
private ManagedDatasource data;
public ManagedDatasource getData() {
return this.data;
}
private static BanStickDatabaseHandler instance;
public static BanStickDatabaseHandler getInstance() {
return BanStickDatabaseHandler.instance;
}
public static ManagedDatasource getinstanceData() {
return BanStickDatabaseHandler.instance.data;
}
public BanStickDatabaseHandler(FileConfiguration config) {
if (!configureData(config.getConfigurationSection("database"))) {
throw new RuntimeException("Failed to configure Database for BanStick!");
}
BanStickDatabaseHandler.instance = this;
}
private boolean configureData(ConfigurationSection config) {
String host = config.getString("host", "localhost");
int port = config.getInt("port", 3306);
String dbname = config.getString("database", "banstick");
String username = config.getString("user");
String password = config.getString("password");
int poolsize = config.getInt("poolsize", 5);
long connectionTimeout = config.getLong("connection_timeout", 10000l);
long idleTimeout = config.getLong("idle_timeout", 600000l);
long maxLifetime = config.getLong("max_lifetime", 7200000l);
try {
data = new ManagedDatasource(BanStick.getPlugin(), username, password, host, port, dbname,
poolsize, connectionTimeout, idleTimeout, maxLifetime);
data.getConnection().close();
} catch (Exception se) {
BanStick.getPlugin().info("Failed to initialize Database connection");
se.printStackTrace();
return false;
}
initializeTables();
stageUpdates();
long begin_time = System.currentTimeMillis();
try {
BanStick.getPlugin().info("Update prepared, starting database update.");
if (!data.updateDatabase()) {
BanStick.getPlugin().info( "Update failed, disabling plugin.");
return false;
}
} catch (Exception e) {
BanStick.getPlugin().severe("Update failed, disabling plugin. Cause:", e);
return false;
}
BanStick.getPlugin().info(String.format("Database update took %d seconds", (System.currentTimeMillis() - begin_time) / 1000));
activatePreload(config.getConfigurationSection("preload"));
activateDirtySave(config.getConfigurationSection("dirtysave"));
return true;
}
private void activateDirtySave(ConfigurationSection config) {
long period = 5*60*50l;
long delay = 5*60*50l;
if (config != null) {
period = config.getLong("period", period);
delay = config.getLong("delay", delay);
}
BanStick.getPlugin().debug("DirtySave Period {0} Delay {1}", period, delay);
Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() {
@Override
public void run() {
BanStick.getPlugin().debug("Player dirty save");
BSPlayer.saveDirty();
}
}, delay, period);
Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() {
@Override
public void run() {
BanStick.getPlugin().debug("Ban dirty save");
BSBan.saveDirty();
}
}, delay + (period / 5), period);
Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() {
@Override
public void run() {
BanStick.getPlugin().debug("Session dirty save");
BSSession.saveDirty();
}
}, delay + ((period * 2) / 5), period);
Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() {
@Override
public void run() {
BanStick.getPlugin().debug("Share dirty save");
BSShare.saveDirty();
}
}, delay + ((period * 3) / 5), period);
Bukkit.getScheduler().runTaskTimerAsynchronously(BanStick.getPlugin(), new Runnable() {
@Override
public void run() {
BanStick.getPlugin().debug("Proxy dirty save");
BSIPData.saveDirty();
}
}, delay + ((period * 4) / 5), period);
BanStick.getPlugin().info("Dirty save tasks started.");
}
private void activatePreload(ConfigurationSection config) {
if (config != null && config.getBoolean("enabled")) {
long period = 5*60*50l;
long delay = 5*60*50l;
period = config.getLong("period", period);
delay = config.getLong("delay", delay);
final int batchsize = config.getInt("batch", 100);
BanStick.getPlugin().debug("Preload Period {0} Delay {1} batch {2}", period, delay, batchsize);
new BukkitRunnable() {
private long lastId = 0l;
@Override
public void run() {
BanStick.getPlugin().debug("IP preload {0}, lim {1}", lastId, batchsize);
lastId = BSIP.preload(lastId, batchsize);
if (lastId < 0) this.cancel();
}
}.runTaskTimerAsynchronously(BanStick.getPlugin(), delay, period);
new BukkitRunnable() {
private long lastId = 0l;
@Override
public void run() {
BanStick.getPlugin().debug("Proxy preload {0}, lim {1}", lastId, batchsize);
lastId = BSIPData.preload(lastId, batchsize);
if (lastId < 0) this.cancel();
}
}.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + (period / 6), period);
new BukkitRunnable() {
private long lastId = 0l;
@Override
public void run() {
BanStick.getPlugin().debug("Ban preload {0}, lim {1}", lastId, batchsize);
lastId = BSBan.preload(lastId, batchsize, false);
if (lastId < 0) this.cancel();
}
}.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 2) / 6), period);
new BukkitRunnable() {
private long lastId = 0l;
@Override
public void run() {
BanStick.getPlugin().debug("Player preload {0}, lim {1}", lastId, batchsize);
lastId = BSPlayer.preload(lastId, batchsize);
if (lastId < 0) this.cancel();
}
}.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 3) / 6), period);
new BukkitRunnable() {
private long lastId = 0l;
@Override
public void run() {
BanStick.getPlugin().debug("Session preload {0}, lim {1}", lastId, batchsize);
lastId = BSSession.preload(lastId, batchsize);
if (lastId < 0) this.cancel();
}
}.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 4) / 6), period);
new BukkitRunnable() {
private long lastId = 0l;
@Override
public void run() {
BanStick.getPlugin().debug("Share preload {0}, lim {1}", lastId, batchsize);
lastId = BSShare.preload(lastId, batchsize);
if (lastId < 0) this.cancel();
}
}.runTaskTimerAsynchronously(BanStick.getPlugin(), delay + ((period * 5) / 6), period);
} else {
BanStick.getPlugin().info("Preloading is disabled. Expect more lag on joins, lookups, and bans.");
}
}
/**
* Basic method to set up data model v1.
*/
private void initializeTables() {
data.registerMigration(0, false,
"CREATE TABLE IF NOT EXISTS bs_player (" +
" pid BIGINT AUTO_INCREMENT PRIMARY KEY," +
" name VARCHAR(16)," +
" uuid CHAR(36) NOT NULL UNIQUE," +
" first_add TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
" bid BIGINT, " +
" ip_pardon_time TIMESTAMP NULL, " +
" proxy_pardon_time TIMESTAMP NULL," +
" shared_pardon_time TIMESTAMP NULL," +
" INDEX bs_player_name (name)," +
" INDEX bs_player_ip_pardons (ip_pardon_time)," +
" INDEX bs_player_proxy_pardons (proxy_pardon_time)," +
" INDEX bs_player_shared_pardons (shared_pardon_time)," +
" INDEX bs_player_join (first_add)" +
");",
"CREATE TABLE IF NOT EXISTS bs_session (" +
" sid BIGINT AUTO_INCREMENT PRIMARY KEY," +
" pid BIGINT," +
" join_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
" leave_time TIMESTAMP NULL," +
" iid BIGINT NOT NULL," +
" INDEX bs_session_pids (pid, join_time, leave_time)" +
");",
"CREATE TABLE IF NOT EXISTS bs_ban_log (" +
" lid BIGINT AUTO_INCREMENT PRIMARY KEY," +
" pid BIGINT NOT NULL," +
" bid BIGINT NOT NULL," +
" action_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
" action VARCHAR(10) NOT NULL," +
" INDEX bs_ban_log_time (pid, action_time DESC)" +
");", // TODO: Whenever a ban is given or removed from a player, record.
"CREATE TABLE IF NOT EXISTS bs_ban (" +
" bid BIGINT AUTO_INCREMENT PRIMARY KEY," +
" ban_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
" ip_ban BIGINT," +
" proxy_ban BIGINT," +
" share_ban BIGINT," +
" admin_ban BOOLEAN DEFAULT FALSE," +
" message TEXT," +
" ban_end TIMESTAMP NULL," +
" INDEX bs_ban_time (ban_time)," +
" INDEX bs_ban_ip (ip_ban)," +
" INDEX bs_ban_proxy (proxy_ban)," +
" INDEX bs_ban_share (share_ban)," +
" INDEX bs_ban_end (ban_end)" +
");",
"CREATE TABLE IF NOT EXISTS bs_share (" +
" sid BIGINT AUTO_INCREMENT PRIMARY KEY," +
" create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
" first_pid BIGINT NOT NULL REFERENCES bs_player(pid)," +
" second_pid BIGINT NOT NULL REFERENCES bs_player(pid)," +
" first_sid BIGINT NOT NULL REFERENCES bs_session(sid)," +
" second_sid BIGINT NOT NULL REFERENCES bs_session(sid)," +
" pardon BOOLEAN DEFAULT FALSE," +
" pardon_time TIMESTAMP NULL," +
" INDEX bs_share (first_pid, second_pid)," +
" INDEX bs_pardon (pardon_time)" +
");",
"CREATE TABLE IF NOT EXISTS bs_ip (" +
" iid BIGINT AUTO_INCREMENT PRIMARY KEY," +
" create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
" ip4 CHAR(15)," +
" ip4cidr SMALLINT," +
" ip6 CHAR(39)," +
" ip6cidr SMALLINT," +
" INDEX bs_session_ip4 (ip4, ip4cidr)," +
" INDEX bs_session_ip6 (ip6, ip6cidr)" +
");",
"CREATE TABLE IF NOT EXISTS bs_ip_data (" +
" idid BIGINT AUTO_INCREMENT PRIMARY KEY," +
" iid BIGINT NOT NULL REFERENCES bs_ip(iid)," +
" create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
" valid BOOLEAN DEFAULT TRUE," +
" continent TEXT," +
" country TEXT," +
" region TEXT," +
" city TEXT," +
" postal TEXT," +
" lat DOUBLE DEFAULT NULL," +
" lon DOUBLE DEFAULT NULL," +
" domain TEXT," +
" provider TEXT," +
" registered_as TEXT," +
" connection TEXT," +
" proxy FLOAT," +
" source TEXT," +
" comment TEXT," +
" INDEX bs_ip_data_iid (iid)," +
" INDEX bs_ip_data_valid (valid, create_time DESC)," +
" INDEX bs_ip_data_proxy (proxy)" +
");",
"ALTER TABLE bs_player ADD CONSTRAINT fk_bs_player_ban " +
" FOREIGN KEY (bid) REFERENCES bs_ban (bid);",
"ALTER TABLE bs_session ADD CONSTRAINT fk_bs_session_player " +
" FOREIGN KEY (pid) REFERENCES bs_player (pid);",
"ALTER TABLE bs_session ADD CONSTRAINT fk_bs_session_iid " +
" FOREIGN KEY (iid) REFERENCES bs_ip (iid);",
"ALTER TABLE bs_ban_log ADD CONSTRAINT fk_bs_ban_log_player " +
" FOREIGN KEY (pid) REFERENCES bs_player (pid);",
"ALTER TABLE bs_ban_log ADD CONSTRAINT fk_bs_ban_log_ban " +
" FOREIGN KEY (bid) REFERENCES bs_ban (bid);",
"ALTER TABLE bs_ban ADD CONSTRAINT fk_bs_ban_ip " +
" FOREIGN KEY (ip_ban) REFERENCES bs_ip (iid);",
"ALTER TABLE bs_ban ADD CONSTRAINT fk_bs_ban_ip_data " +
" FOREIGN KEY (proxy_ban) REFERENCES bs_ip_data (idid);",
"ALTER TABLE bs_ban ADD CONSTRAINT fk_bs_ban_share " +
" FOREIGN KEY (share_ban) REFERENCES bs_share (sid);"
);
data.registerMigration(1, false, "CREATE TABLE IF NOT EXISTS bs_exclusion ("
+ "eid BIGINT AUTO_INCREMENT PRIMARY KEY,"
+ "create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,"
+ "first_pid BIGINT NOT NULL REFERENCES bs_player(pid),"
+ "second_pid BIGINT NOT NULL REFERENCES bs_player(pid),"
+ " INDEX bs_exclusion_pid (first_pid, second_pid)"
+ ");");
data.registerMigration(2, false, "CREATE TABLE IF NOT EXISTS bs_banned_registrars ("
+ "rid BIGINT AUTO_INCREMENT PRIMARY KEY,"
+ "create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,"
+ "registered_as text"
+ ");");
}
/**
* Add all new migrations here.
*/
private void stageUpdates() {
}
public void doShutdown() {
BanStick.getPlugin().info("Player dirty save");
BSPlayer.saveDirty();
BanStick.getPlugin().info("Ban dirty save");
BSBan.saveDirty();
BanStick.getPlugin().info("Session dirty save");
BSSession.saveDirty();
BanStick.getPlugin().info("Share dirty save");
BSShare.saveDirty();
BanStick.getPlugin().info("Proxy dirty save");
BSIPData.saveDirty();
BanStick.getPlugin().info("Ban Log save");
BSLog log = BanStick.getPlugin().getLogHandler();
if (log != null) log.disable();
}
// ============ QUERIES =============
public BSPlayer getOrCreatePlayer(final Player player) {
// TODO: use exception
BSPlayer bsPlayer = getPlayer(player.getUniqueId());
if (bsPlayer == null) {
bsPlayer = BSPlayer.create(player);
}
return bsPlayer;
}
public BSPlayer getPlayer(final UUID uuid) {
return BSPlayer.byUUID(uuid); // TODO: exception
}
public BSIP getOrCreateIP(final InetAddress netAddress) {
BSIP bsIP = getIP(netAddress);
if (bsIP == null) {
BanStick.getPlugin().debug("Creating IP address: {0}", netAddress);
bsIP = BSIP.create(netAddress);
} else {
BanStick.getPlugin().info("Registering future retrieval of IPData for {0}", bsIP.toString());
BanStick.getPlugin().getIPDataHandler().offer(bsIP);
}
return bsIP;
}
public BSIP getIP(final InetAddress netAddress) {
return BSIP.byInetAddress(netAddress);
}
public List<BSIP> getAllByIP(final InetAddress netAddress) {
return BSIP.allMatching(netAddress);
}
}