Hello Folks.
My name's Nick. I'm a[n] experienced Java developer and have loved to explore my way through the several different server APIs for Minecraft, including but not limited to, BukkitAPI, BungeeAPI and Granite. I also have tons of experienced with program MySQL, and the SQL language.
I created this Network Lib a-couple days ago, I'd consider it very efficient if the desired user isn't using a Proxying Software for their server that has the ability to send network messages, e.g. BungeeCord.
NPlayer data = NicksLib.getInstance().players.get(player);
Once you have your data variable, you're able todo quite a bit.
This class contains several useful methods, like retrieving the player, saving the player.
The only listener class in the plugin.
Explanation, this API is for testing purposes. If you're wanting to mess around with MySQL storing, and not want to convert your volatile data to Configuration (.yml) or otherwise Stream related files.
How it works: The code is very detailed, and shows for the most part everything that you need to know!
You can download the .jar here.
https://nicksums.com/plugins/networklib/NicksLib.jar
You can download the .zip src here.
https://nicksums.com/plugins/networklib/networklib-src.zip
My name's Nick. I'm a[n] experienced Java developer and have loved to explore my way through the several different server APIs for Minecraft, including but not limited to, BukkitAPI, BungeeAPI and Granite. I also have tons of experienced with program MySQL, and the SQL language.
I created this Network Lib a-couple days ago, I'd consider it very efficient if the desired user isn't using a Proxying Software for their server that has the ability to send network messages, e.g. BungeeCord.
Network Lib
Firstly, grab the player like so..
NPlayer data = NicksLib.getInstance().players.get(player);
Once you have your data variable, you're able todo quite a bit.
Code:
data.getPlayer();
Returns Player
data.getPlayerUUID();
Returns UUID
data.getLanguage();
Returns Language String.
data.setLanguage(String lang);
Requires String, sets language.
/*
Level methods
*/
data.getLevel();
returns int
data.addLevel(int level);
Requires int, adds to level.
data.removeLevel(int level);
Requires int, removes level.
data.setLevel(int level);
Sets the player level.
/*
Experience related methods
*/
data.getExperience();
returns float.
data.addExperience(float experience)
requires float, adds to experience.
data.removeExperience(float experience)
requires float removes from experience.
data.setExperience(float experience)
requires float sets experience.
/*
Credits related methods
*/
data.getCredits();
returns int
data.addCredits(int credits);
requires int, adds credits
data.removeCredits(int credits)
requires int, removes credits.
data.setCredits(int credits)
requires int, sets credits.
/*
Achievement Points
*/
data.getAchievementPoints();
returns int.
data.addAchievementPoints(int amount)
requires int adds to achievement points.
data.removeAchievementPoints(int amount);
requires int removes from achievement points.
data.setAchievementPoints(int amount)
requires int sets achievement points
This class contains several useful methods, like retrieving the player, saving the player.
Code:
package com.nicksums.lib.api;
import com.mysql.jdbc.Statement;
import com.nicksums.lib.NicksLib;
import com.nicksums.lib.mechanics.NPlayer;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Created by Nick on 6/15/2015.
*/
public class API {
/*
This class will contain all of our MySQL methods, excluding the few that are harbored
inside the main class, that extends JavaPlugin.
*/
/*
Saving the player
*/
public static void savePlayer(final Player player) {
PreparedStatement state = null;
try {
/*
Now, time to grab the storage of our player.
*/
NPlayer data = NicksLib.getInstance().players.get(player);
state = NicksLib.getInstance().database.prepareStatement("UPDATE `" + NicksLib.getInstance().table + "` SET lang=?,level=?,experience=?,credits=?,achievement_points=? WHERE id=?;");
/*
Here we're setting the ?'s, with PreparedStatement's Methods. set(This,That).
*/
state.setString(1, data.getLanguage());
state.setInt(2, data.getLevel());
state.setFloat(3, data.getExperience());
state.setInt(4, data.getCredits());
state.setInt(5, data.getAchievementPoints());
state.setInt(6, data.getUniqueId());
state.execute();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
state.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/*
This method, will grab the players uniqueId if the player is new.
*/
public static int addNewPlayer(final Player player) {
PreparedStatement state = null;
ResultSet set = null;
try {
state = NicksLib.getInstance().database.prepareStatement("INSERT INTO `" + NicksLib.getInstance().table + "` (uuid) VALUES (?);", Statement.RETURN_GENERATED_KEYS);
/*
state.setString() ask for an (int) which corresponds to the statement above, 1 represents the first question mark.
Starting from left to right. (?).
And we're setting that question mark = to player.getUniqueId().toString(). Since the uuid is stored as a Varchar
corresponding to a String via Java.
*/
state.setString(1, player.getUniqueId().toString());
state.execute();
set = state.getGeneratedKeys();
if (set.next()) {
return set.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
state.close();
set.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/*
If we're unable to do this, let's return a form of volatile data to we can check elseware.
*/
return -1;
}
/*
This method will fetch the player from the MySQL Server.
It's a list of Objects because we'll be returning several different
types of data to store volatile, and save later.
*/
public static Object[] getPlayer(final Player player) {
/*
Set the size of the Object.
Remember the Object[SIZE] has to be 1 larger than your final input.
*/
Object[] obj = new Object[8];
/*
Set the first list of the Object[] to a boolean value.
This value will be set to false before the SQL is contacted.
Let's say for example the player doesn't exist in the MySQL.
Then the first value of the object[] will be a boolean of type false.
Later in the statement we'll set this obj[0] = true;
*/
obj[0] = false;
/*
DBMS can run PreparedStatement without SQL statement without having to compile it first.
ResultSet usually means you're retrieving data from MySQL, data is returned in the form of a
(ResultSet)!
Both are declared, null. So later in the method after a finally{} they can be halted.
*/
PreparedStatement state = null;
ResultSet set = null;
try {
/*
Set the state equal to the instantiation of the main class database variable.
Make sure to always end a MySQL PreparedStatement with a ';'.
*/
state = NicksLib.getInstance().database.prepareStatement("SELECT id,uuid,lang,level,experience,credits,achievement_points FROM `" + NicksLib.getInstance().table + "` WHERE uuid=?;");
/*
Set the first question mark in the PreparedStatement = to the StringValue of the UniqueId.
*/
state.setString(1, player.getUniqueId().toString());
/*
Execute Query is a return type of ResultSet, which is (set).
*/
set = state.executeQuery();
/*
If the database has results to return from the PreparedStatement the results will be returned inside this if.
*/
if (set.next()) {
/*
Set the object as defined above, = to something useful.
For the sake of this lib, we're requesting an
INT id,
VARCHAR uuid //VarChar is like.. a String.
VARCHAR lang,
INT level,
FLOAT experience,
INT credits,
INT achievement_points
*/
obj[0] = true;
/*
Make sure to checkout ResultSet, methods.
set as defined above . has abunch of useful methods to
fetch data from a given ResultSet. e.g. getInt, getFloat, getString..
*/
obj[1] = set.getInt("id");
obj[2] = set.getString("uuid");
obj[3] = set.getString("lang");
obj[4] = set.getInt("level");
obj[5] = set.getFloat("experience");
obj[6] = set.getInt("credits");
obj[7] = set.getInt("achievement_points");
}
return obj;
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
state.close();
set.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return obj;
}
/*
Nice little Reflection method to grab the players default Language.
The language the player chooses at the GuiMainMenu of Minecraft.
*/
public static String getLanguage(Player p) {
Object ep = null;
try {
ep = getMethod("getHandle", p.getClass()).invoke(p, (Object[]) null);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
Field f = null;
try {
f = ep.getClass().getDeclaredField("locale");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
f.setAccessible(true);
String language = null;
try {
language = (String) f.get(ep);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return language;
}
/*
Dependency method for above.
*/
private static Method getMethod(String name, Class<?> clazz) {
for (Method m : clazz.getDeclaredMethods()) {
if (m.getName().equals(name))
return m;
}
return null;
}
}
Code:
package com.nicksums.lib.listeners;
import com.nicksums.lib.NicksLib;
import com.nicksums.lib.api.API;
import com.nicksums.lib.mechanics.InvalidUniqueIdException;
import com.nicksums.lib.mechanics.NPlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
/**
* Created by Nick on 6/15/2015.
*/
public class LibListener implements Listener {
/*
Declare the method as an event to be watched with @EventHandler.
Declare the method as a higher level priority event. via EventPriority.
So that other plugins on the server can't take our priority of making sure
that the player is existing or not.
PlayerLoginEvent is executed before PlayerJoinEvent.
*/
@EventHandler(priority = EventPriority.HIGH)
public void onLogin(PlayerLoginEvent event) {
/*
Create the player variable, set instantiate.
*/
Player player = event.getPlayer();
/*
Declare a Object[]
Remember that our API.getPLayer() returns type of Object[]
*/
Object[] thePlayer = API.getPlayer(player);
/*
The player exist!
*/
if (thePlayer[0] == true) {
/*
So.. Since the player exist in the database, we'll just grab the Object[]'s contents and set it to the volatile storage of the HashMap<>.
*/
NicksLib.getInstance().players.put(player, new NPlayer(player, (int) thePlayer[1], (String)thePlayer[3], (int) thePlayer[4], (float) thePlayer[5], (int) thePlayer[6], (int) thePlayer[7]));
}
/*
The player doesn't exist!
*/
else if (thePlayer[0] == false) {
int uniqueId = API.addNewPlayer(player);
if (uniqueId != -1) {
/*
Perfect, the api was able to return is a valid number and wasn't -1.
Now, we have a fresh player and must set the players defaults.
Check constructor of (NPlayer) for more information regarding this.
Let's remember that NPlayer Constructor contains
Player, UniqueId, Level, Experience, Credits, Achievement Points.
*/
NicksLib.getInstance().players.put(player, new NPlayer(player, uniqueId, API.getLanguage(player), 0, 0f, 0, 0));
}else {
new InvalidUniqueIdException("Unable to handle PlayerJoinEvent() Event for Player: " + player.getName() + " with uniqueIdentifier " + uniqueId);
}
}
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
/*
Now, since the player has left, let's remove the players storage.
Else, the server will hold this information in memory as volaitle
data until the memory is flushed. (Restarted)!
*/
if(NicksLib.getInstance().players.containsKey(player)) {
API.savePlayer(player);
NicksLib.getInstance().players.remove(player);
}
}
}
Explanation, this API is for testing purposes. If you're wanting to mess around with MySQL storing, and not want to convert your volatile data to Configuration (.yml) or otherwise Stream related files.
How it works: The code is very detailed, and shows for the most part everything that you need to know!
You can download the .jar here.
https://nicksums.com/plugins/networklib/NicksLib.jar
You can download the .zip src here.
https://nicksums.com/plugins/networklib/networklib-src.zip