Skip to content

Instantly share code, notes, and snippets.

@effective-light
Last active June 20, 2017 07:12
Show Gist options
  • Select an option

  • Save effective-light/3628244154b2c88ef741 to your computer and use it in GitHub Desktop.

Select an option

Save effective-light/3628244154b2c88ef741 to your computer and use it in GitHub Desktop.
NoSQL connection pooling
package net.atomiccloud.acndatabase.bungee;
import net.atomiccloud.acndatabase.GameMode;
import net.atomiccloud.acndatabase.bungee.data.Statistics;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public interface Database {
Statistics getStatistics(GameMode game, ProxiedPlayer player);
}
public class DatabaseAPI {
private static ACNDatabasePlugin plugin;
public DatabaseAPI(ACNDatabasePlugin plugin) {
DatabaseAPI.plugin = plugin;
}
public static Database getDatabase() {
return plugin.getDatabase();
}
}
package net.atomiccloud.acndatabase;
public enum GameMode
{
SKY_WARS( "Sky Wars" ), SUMO( "Sumo" ), FFA( "FFA" ), X_RUN( "X RUN" ), KIT_PVP( "Kit PVP" );
private String name;
GameMode(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public static GameMode getByName(String name)
{
for ( GameMode game : values() )
{
if ( name.equals( game.getName() ) ) return game;
}
return null;
}
}
public class MessageListener implements Listener
{
ACNDatabasePlugin plugin;
public MessageListener(ACNDatabasePlugin plugin)
{
this.plugin = plugin;
}
@EventHandler
public void onPluginMessage(PluginMessageEvent event)
{
if ( !( event.getSender() instanceof Server ) ||
!event.getTag().equals("Database")) return;
event.setCancalled( true );
ByteArrayInputStream input = new ByteArrayInputStream( event.getData() );
ObjectInputStream objectInput = new ObjectInputStream( input );
Statistics statistics = objectInput.readObject();
}
}
package net.atomiccloud.acndatabase.bungee.data;
import com.mongodb.*;
import net.atomiccloud.acndatabase.GameMode;
import net.atomiccloud.acndatabase.bungee.Database;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class MongoDatabase implements Database
{
private DBCollection collection;
private Map<UUID, Map<GameMode, Statistics>> statsCache = new HashMap<>();
public MongoDatabase()
{
try
{
MongoClient mongoClient = new MongoClient( "localhost", 27017 );
DB db = mongoClient.getDB( "db-name" );
collection = db.getCollection( "stats" );
} catch ( UnknownHostException e )
{
e.printStackTrace();
}
}
public Statistics addNewPlayer(GameMode game, ProxiedPlayer player)
{
BasicDBObject document = new BasicDBObject();
document.put( "_id", player.getUniqueId() );
document.put( "gameMode", game.getName() );
document.put( "kills", 0L );
document.put( "deaths", 0L );
document.put( "wins", 0L );
document.put( "losses", 0L );
collection.insert( document );
Statistics statistics = new Statistics( collection, player.getUniqueId(),
game, 0L, 0L, 0L, 0L );
updateCache( player, game, statistics );
return statistics;
}
private void updateCache(ProxiedPlayer player, GameMode game, Statistics statistics)
{
if ( statsCache.containsKey( player.getUniqueId() ) )
{
Map<GameMode, Statistics> map = statsCache.get( player.getUniqueId() );
map.put( game, statistics );
statsCache.put( player.getUniqueId(), map );
} else
{
Map<GameMode, Statistics> tempMap = new HashMap<>();
tempMap.put( game, statistics );
statsCache.put( player.getUniqueId(), tempMap );
}
}
@Override
public Statistics getStatistics(GameMode game, ProxiedPlayer player)
{
if ( statsCache.containsKey( player.getUniqueId() )
&& statsCache.get( player.getUniqueId() ).containsKey( game ) )
{
return statsCache.get( player.getUniqueId() ).get( game );
}
Statistics statistics = playerExists( game, player );
if ( statistics != null )
{
Map<GameMode, Statistics> tempMap = new HashMap<>();
tempMap.put( game, statistics );
statsCache.put( player.getUniqueId(), tempMap );
return statistics;
}
return addNewPlayer( game, player );
}
private Statistics playerExists(GameMode game, ProxiedPlayer player)
{
DBCursor cursor = collection.find( new BasicDBObject( "_id",
player.getUniqueId() ).append( "gameMode", game.getName() ) ).limit( 1 );
if ( cursor.hasNext() )
{
DBObject object = cursor.one();
return new Statistics( collection, player.getUniqueId(), game,
(long) object.get( "kills" ), (long) object.get( "deaths" ),
(long) object.get( "wins" ), (long) object.get( "losses" ) );
}
return null;
}
}
package net.atomiccloud.acndatabase.bungee;
import net.atomiccloud.acndatabase.bungee.data.MongoDatabase;
import net.md_5.bungee.api.plugin.Plugin;
public class ACNDatabasePlugin extends Plugin
{
private Database database;
@Override
public void onEnable()
database = new MongoDatabase();
getProxy().getPluginManager().registerListener( new MessageListener( this ) );
getProxy().registerChannel( "Database" );
getProxy().registerChannel( "ACNDatabase" );
}
public Database getDatabase()
{
return database;
}
}
package net.atomiccloud.acndatabase.bungee.data;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import net.atomiccloud.acndatabase.GameMode;
import java.util.UUID;
public class Statistics implements Serializable
{
DBCollection collection;
private UUID playerUuid;
private GameMode game;
private long kills;
private long deaths;
private long wins;
private long losses;
private long cosmites;
private static final long serialVersionUID = 69L;
public Statistics(DBCollection collection, UUID playerUuid, GameMode game,
long kills, long deaths, long wins, long losses, long cosmites)
{
this.collection = collection;
this.playerUuid = playerUuid;
this.game = game;
this.kills = kills;
this.deaths = deaths;
this.wins = wins;
this.losses = losses;
this.cosmites = cosmites;
}
public long getDeaths()
{
return deaths;
}
public long getKills()
{
return kills;
}
public long getWins()
{
return wins;
}
public long getLosses()
{
return losses;
}
public long getCosmites()
{
return cosmites;
}
public void incrKills()
{
handleIncr( "kills" );
kills++;
}
public void incrDeaths()
{
handleIncr( "deaths" );
deaths++;
}
public void incrWins()
{
handleIncr( "wins" );
wins++;
}
public void incrLosses()
{
handleIncr( "losses" );
losses++;
}
public void addCosmites(long amount)
{
handleIncr( "cosmites", amount );
cosmites += amount;
}
public void removeCosmites(long amount)
{
handleIncr( "cosmites", -amount );
cosmites -= amount;
}
private void handleIncr(String element)
{
handleIncr( element, 1L );
}
private void inc(String element, long amount)
{
BasicDBObject newDocument = new BasicDBObject().append(
"$inc", new BasicDBObject().append( element, amount ) );
collection.update( new BasicDBObject( "_id", playerUuid )
.append( "gameMode", game.getName() ), newDocument );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment