Skip to content

Commit 1a53c13

Browse files
author
TheProgramSrc
committed
ChangeLog:
• Added GlobalStorage and MemoryStorage
1 parent 00f25e7 commit 1a53c13

File tree

8 files changed

+269
-3
lines changed

8 files changed

+269
-3
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>xyz.theprogramsrc</groupId>
88
<artifactId>SuperCoreAPI</artifactId>
9-
<version>3.1.1</version>
9+
<version>3.2.0</version>
1010
<packaging>jar</packaging>
1111

1212
<name>SuperCoreAPI</name>

src/main/java/xyz/theprogramsrc/supercoreapi/SuperPlugin.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,9 @@ default String getPluginMessagingChannelName(){
153153
* @return Dependency Manager
154154
*/
155155
DependencyManager getDependencyManager();
156+
157+
/**
158+
* Stops the plugin
159+
*/
160+
void emergencyStop();
156161
}

src/main/java/xyz/theprogramsrc/supercoreapi/bungee/BungeePlugin.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
public abstract class BungeePlugin extends Plugin implements SuperPlugin<Plugin> {
2525

26-
private boolean firstStart;
26+
private boolean firstStart, emergencyStop;
2727
private List<Runnable> disableHooks;
2828
private File translationsFolder;
2929

@@ -34,17 +34,20 @@ public abstract class BungeePlugin extends Plugin implements SuperPlugin<Plugin>
3434
@Override
3535
public void onLoad() {
3636
long start = System.currentTimeMillis();
37+
this.emergencyStop = false;
3738
new xyz.theprogramsrc.Base();
3839
this.log("Loading plugin &3v"+this.getPluginVersion());
3940
this.disableHooks = new ArrayList<>();
4041
this.firstStart = !this.getDataFolder().exists();
4142
Utils.folder(this.getDataFolder());
4243
this.onPluginLoad();
44+
if(this.emergencyStop) return;
4345
this.log("Loaded plugin in " + (System.currentTimeMillis() - start) + "ms");
4446
}
4547

4648
@Override
4749
public void onEnable() {
50+
if(this.emergencyStop) return;
4851
this.log("Enabling plugin &3v" + this.getPluginVersion());
4952
this.settings = new Settings(this);
5053
this.translationsFolder = Utils.folder(new File(this.getDataFolder(), "translations/"));
@@ -69,6 +72,7 @@ public void onEnable() {
6972

7073
@Override
7174
public void onDisable() {
75+
if(this.emergencyStop) return;
7276
this.log("Disabling plugin &3v" + this.getPluginVersion());
7377
this.getDisableHooks().forEach(Runnable::run);
7478
this.onPluginDisable();
@@ -157,4 +161,15 @@ public Settings getSettings() {
157161
public DependencyManager getDependencyManager() {
158162
return dependencyManager;
159163
}
164+
165+
/**
166+
* Not recommended in bungeecord because this is not an official way to disable a plugin
167+
*/
168+
@Override
169+
public void emergencyStop() {
170+
this.emergencyStop = true;
171+
this.onDisable();
172+
this.getProxy().getPluginManager().unregisterCommands(this);
173+
this.getProxy().getPluginManager().unregisterListeners(this);
174+
}
160175
}

src/main/java/xyz/theprogramsrc/supercoreapi/global/storage/DataBaseStorage.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,19 @@ protected int requestLastInsertedID(Connection connection, String table) {
5555
}
5656

5757

58+
/**
59+
* Gets the plugin
60+
* @return the plugin
61+
*/
62+
public SuperPlugin<?> getPlugin() {
63+
return plugin;
64+
}
65+
66+
/**
67+
* Gets the DataBase that it's being used
68+
* @return the database
69+
*/
70+
public DataBase getDataBase() {
71+
return dataBase;
72+
}
5873
}

src/main/java/xyz/theprogramsrc/supercoreapi/global/storage/SQLiteDataBase.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,13 @@ public void connect(ConnectionCall call) {
7575
ex.printStackTrace();
7676
}
7777
}
78+
79+
/**
80+
* This is not needed because SQLite doesn't use credentials
81+
* @return null
82+
*/
83+
@Override
84+
public DataBaseSettings getDataBaseSettings() {
85+
return null;
86+
}
7887
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package xyz.theprogramsrc.supercoreapi.global.storage.global;
2+
3+
import xyz.theprogramsrc.supercoreapi.SuperPlugin;
4+
import xyz.theprogramsrc.supercoreapi.global.storage.DataBaseStorage;
5+
import xyz.theprogramsrc.supercoreapi.global.storage.MySQLDataBase;
6+
7+
import java.sql.ResultSet;
8+
import java.sql.Statement;
9+
import java.util.HashMap;
10+
import java.util.concurrent.atomic.AtomicBoolean;
11+
import java.util.concurrent.atomic.AtomicReference;
12+
13+
/**
14+
* Representation of a Storage that can be used in Bungee and Spigot
15+
* @param <OBJ> the main object to store
16+
*/
17+
public abstract class GlobalStorage<OBJ> extends DataBaseStorage {
18+
19+
private HashMap<String, OBJ> cache;
20+
21+
public GlobalStorage(SuperPlugin<?> plugin, MySQLDataBase mySQLDataBase){
22+
super(plugin, mySQLDataBase);
23+
this.cache = new HashMap<>();
24+
this.preloadTable();
25+
}
26+
27+
/**
28+
* Gets the table where the {@link OBJ object} should be saved
29+
* @return the name of the table
30+
*/
31+
public abstract String getTableName();
32+
33+
/**
34+
* Used to serialize and store in the database
35+
* @param obj the {@link OBJ object}
36+
* @return the serialized {@link OBJ object}
37+
*/
38+
public abstract String serialize(OBJ obj);
39+
40+
/**
41+
* Used to deserialize the Stored Data
42+
* @param data the data
43+
* @return the object
44+
*/
45+
public abstract OBJ deserialize(String data);
46+
47+
/**
48+
* Store the {@link OBJ object} in the database
49+
* @param key the key
50+
* @param value the object
51+
*/
52+
public void save(final String key, OBJ value){
53+
this.cache.remove(key);
54+
final String data = this.serialize(value);
55+
this.dataBase.connect(c->{
56+
try{
57+
Statement s = c.createStatement();
58+
if(this.exists(key)){
59+
s.executeUpdate("UPDATE " + this.getTableName() + " SET object_value='"+data+"' WHERE object_key='"+key+"';");
60+
}else{
61+
s.executeUpdate("INSERT INTO " + this.getTableName() + " (object_key, object_value) VALUES ('"+key+"','"+data+"')");
62+
}
63+
}catch (Exception ex){
64+
this.plugin.log("&cCannot save data with key: '" + key + "'");
65+
ex.printStackTrace();
66+
}
67+
});
68+
}
69+
70+
/**
71+
* Gets the {@link OBJ object} from the database
72+
* @param key the key
73+
* @return the object
74+
*/
75+
public OBJ get(final String key){
76+
if(this.cache.containsKey(key)) return this.cache.get(key);
77+
AtomicReference<OBJ> obj = new AtomicReference<>(null);
78+
this.dataBase.connect(c->{
79+
try{
80+
Statement s = c.createStatement();
81+
ResultSet rs = s.executeQuery("SELECT * FROM " + this.getTableName() + " WHERE object_key='"+key+"'");
82+
if(rs.next()){
83+
obj.set(this.deserialize(rs.getString("object_value")));
84+
}
85+
}catch (Exception ex){
86+
this.plugin.log("&cCannot fetch data with key: '" + key + "'");
87+
ex.printStackTrace();
88+
}
89+
});
90+
return obj.get();
91+
}
92+
93+
/**
94+
* Used to get all the {@link OBJ object} stored in the database
95+
* @return the objects
96+
*/
97+
public HashMap<String, OBJ> getAll(){
98+
HashMap<String, OBJ> objs = new HashMap<>();
99+
100+
this.dataBase.connect(c->{
101+
try{
102+
Statement s = c.createStatement();
103+
ResultSet rs = s.executeQuery("SELECT * FROM " + this.getTableName() + ";");
104+
while(rs.next()){
105+
String key = rs.getString("object_key");
106+
String value = rs.getString("object_value");
107+
OBJ obj = this.deserialize(value);
108+
objs.put(key, obj);
109+
}
110+
}catch (Exception ex){
111+
this.plugin.log("&cCouldn't fetch data:");
112+
ex.printStackTrace();
113+
}
114+
});
115+
this.cache = new HashMap<>(objs);
116+
return objs;
117+
}
118+
119+
/**
120+
* Checks if the {@link OBJ object} is stored in the database
121+
* @param key the key
122+
* @return true if is stored, otherwise false
123+
*/
124+
public boolean exists(final String key){
125+
AtomicBoolean exist = new AtomicBoolean(false);
126+
this.dataBase.connect(c->{
127+
try{
128+
Statement s = c.createStatement();
129+
exist.set(s.executeQuery("SELECT * FROM " + this.getTableName() + " WHERE object_key='"+key+"';").next());
130+
}catch (Exception ex){
131+
this.plugin.log("&cCannot fetch data with key: '" + key + "'");
132+
ex.printStackTrace();
133+
}
134+
});
135+
136+
return exist.get();
137+
}
138+
139+
private void preloadTable(){
140+
this.dataBase.connect(c->{
141+
try{
142+
Statement s = c.createStatement();
143+
s.executeUpdate("CREATE TABLE IF NOT EXISTS " + this.getTableName() + " (object_key VARCHAR(200), object_value LONGTEXT);");
144+
}catch (Exception ex){
145+
this.plugin.log("&cCouldn't load Table:");
146+
ex.printStackTrace();
147+
}
148+
});
149+
}
150+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package xyz.theprogramsrc.supercoreapi.global.storage.memory;
2+
3+
import xyz.theprogramsrc.supercoreapi.SuperPlugin;
4+
5+
import java.util.LinkedHashMap;
6+
import java.util.LinkedList;
7+
import java.util.Map;
8+
import java.util.Set;
9+
import java.util.function.BiConsumer;
10+
11+
public class MemoryStorage<OBJ> {
12+
13+
protected SuperPlugin<?> plugin;
14+
protected LinkedHashMap<String, OBJ> memory;
15+
16+
public MemoryStorage(SuperPlugin<?> plugin){
17+
this.plugin = plugin;
18+
this.memory = new LinkedHashMap<>();
19+
}
20+
21+
public void add(String key, OBJ value){
22+
if(!this.memory.containsKey(key)){
23+
this.memory.put(key, value);
24+
}
25+
}
26+
27+
public void set(String key, OBJ value){
28+
this.memory.put(key, value);
29+
}
30+
31+
public void remove(String key){
32+
this.memory.remove(key);
33+
}
34+
35+
public boolean has(String key){
36+
return this.memory.containsKey(key);
37+
}
38+
39+
public boolean has(OBJ value){
40+
return this.memory.containsValue(value);
41+
}
42+
43+
public void forEach(BiConsumer<String, OBJ> consumer){
44+
this.memory.forEach(consumer);
45+
}
46+
47+
public Set<Map.Entry<String,OBJ>> entrySet(){
48+
return this.memory.entrySet();
49+
}
50+
51+
public LinkedList<String> keys(){
52+
final LinkedList<String> keys = new LinkedList<>();
53+
this.forEach((k,v)-> keys.add(k));
54+
return keys;
55+
}
56+
57+
public LinkedList<OBJ> values(){
58+
final LinkedList<OBJ> values = new LinkedList<>();
59+
this.forEach((k,v)-> values.add(v));
60+
return values;
61+
}
62+
}

src/main/java/xyz/theprogramsrc/supercoreapi/spigot/SpigotPlugin.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
public abstract class SpigotPlugin extends JavaPlugin implements SuperPlugin<JavaPlugin> {
2727

28-
private boolean firstStart;
28+
private boolean firstStart, emergencyStop;
2929
private List<Runnable> disableHooks;
3030
private File serverFolder, translationsFolder;
3131

@@ -39,18 +39,21 @@ public abstract class SpigotPlugin extends JavaPlugin implements SuperPlugin<Jav
3939
@Override
4040
public void onLoad() {
4141
long current = System.currentTimeMillis();
42+
this.emergencyStop = false;
4243
new xyz.theprogramsrc.Base();
4344
this.log("Loading plugin &3v"+this.getPluginVersion());
4445
this.disableHooks = new ArrayList<>();
4546
this.serverFolder = Utils.folder(new File("."));
4647
this.firstStart = !this.getDataFolder().exists();
4748
Utils.folder(this.getDataFolder());
4849
this.onPluginLoad();
50+
if(this.emergencyStop) return;
4951
this.log("Loaded plugin in " + (System.currentTimeMillis() - current) + "ms");
5052
}
5153

5254
@Override
5355
public void onEnable() {
56+
if(this.emergencyStop) return;
5457
this.log("Enabling plugin &3v" + this.getPluginVersion());
5558
this.settingsStorage = new SettingsStorage(this);
5659
this.translationsFolder = Utils.folder(new File(this.getDataFolder(), "translations/"));
@@ -77,6 +80,7 @@ public void onEnable() {
7780

7881
@Override
7982
public void onDisable() {
83+
if(this.emergencyStop) return;
8084
this.log("Disabling plugin &3v" + this.getPluginVersion());
8185
this.getDisableHooks().forEach(Runnable::run);
8286
this.onPluginDisable();
@@ -215,4 +219,10 @@ public DependencyManager getDependencyManager() {
215219
public SkinTextureManager getSkinManager() {
216220
return skinManager;
217221
}
222+
223+
@Override
224+
public void emergencyStop() {
225+
this.emergencyStop = true;
226+
this.getServer().getPluginManager().disablePlugin(this);
227+
}
218228
}

0 commit comments

Comments
 (0)