2011-10-08 22:03:44 +02:00
package com.massivecraft.factions.zcore ;
2014-10-25 20:22:41 +02:00
import com.google.gson.Gson ;
import com.google.gson.GsonBuilder ;
import com.google.gson.reflect.TypeToken ;
2014-10-19 07:37:25 +02:00
import com.massivecraft.factions.Board ;
2014-04-04 20:55:21 +02:00
import com.massivecraft.factions.Conf ;
2014-10-19 07:37:25 +02:00
import com.massivecraft.factions.FPlayers ;
import com.massivecraft.factions.Factions ;
2014-04-04 20:55:21 +02:00
import com.massivecraft.factions.zcore.persist.SaveTask ;
import com.massivecraft.factions.zcore.util.PermUtil ;
import com.massivecraft.factions.zcore.util.Persist ;
2014-07-01 20:19:36 +02:00
import com.massivecraft.factions.zcore.util.TL ;
2014-04-04 20:55:21 +02:00
import com.massivecraft.factions.zcore.util.TextUtil ;
import org.bukkit.Bukkit ;
import org.bukkit.command.CommandSender ;
2014-07-01 20:19:36 +02:00
import org.bukkit.configuration.file.YamlConfiguration ;
2014-04-04 20:55:21 +02:00
import org.bukkit.plugin.java.JavaPlugin ;
2014-07-01 20:19:36 +02:00
import java.io.* ;
2011-10-08 22:03:44 +02:00
import java.lang.reflect.Modifier ;
import java.lang.reflect.Type ;
import java.util.* ;
2011-10-10 13:31:25 +02:00
import java.util.Map.Entry ;
2011-10-08 22:03:44 +02:00
import java.util.logging.Level ;
2014-04-04 20:55:21 +02:00
public abstract class MPlugin extends JavaPlugin {
2014-08-05 17:17:27 +02:00
2014-04-04 20:55:21 +02:00
// Some utils
public Persist persist ;
public TextUtil txt ;
public PermUtil perm ;
2011-10-08 22:03:44 +02:00
2014-04-04 20:55:21 +02:00
// Persist related
public Gson gson ;
private Integer saveTask = null ;
private boolean autoSave = true ;
protected boolean loadSuccessful = false ;
public boolean getAutoSave ( ) {
return this . autoSave ;
}
2013-04-18 10:02:40 +02:00
2014-04-04 20:55:21 +02:00
public void setAutoSave ( boolean val ) {
this . autoSave = val ;
}
2011-10-08 22:03:44 +02:00
2014-04-04 20:55:21 +02:00
public String refCommand = " " ;
// Listeners
private MPluginSecretPlayerListener mPluginSecretPlayerListener ;
private MPluginSecretServerListener mPluginSecretServerListener ;
// Our stored base commands
private List < MCommand < ? > > baseCommands = new ArrayList < MCommand < ? > > ( ) ;
public List < MCommand < ? > > getBaseCommands ( ) {
return this . baseCommands ;
}
2015-05-13 05:16:47 +02:00
// holds f stuck start times
private Map < UUID , Long > timers = new HashMap < UUID , Long > ( ) ;
//holds f stuck taskids
public Map < UUID , Integer > stuckMap = new HashMap < UUID , Integer > ( ) ;
2014-04-04 20:55:21 +02:00
// -------------------------------------------- //
// ENABLE
// -------------------------------------------- //
private long timeEnableStart ;
public boolean preEnable ( ) {
2014-07-01 22:10:18 +02:00
log ( " === ENABLE START === " ) ;
timeEnableStart = System . currentTimeMillis ( ) ;
2014-04-04 20:55:21 +02:00
// Ensure basefolder exists!
this . getDataFolder ( ) . mkdirs ( ) ;
// Create Utility Instances
2014-07-01 22:10:18 +02:00
this . perm = new PermUtil ( this ) ;
this . persist = new Persist ( this ) ;
2014-04-04 20:55:21 +02:00
// GSON 2.1 is now embedded in CraftBukkit, used by the auto-updater: https://github.com/Bukkit/CraftBukkit/commit/0ed1d1fdbb1e0bc09a70bc7bfdf40c1de8411665
2012-03-11 13:39:31 +01:00
// if ( ! lib.require("gson.jar", "http://search.maven.org/remotecontent?filepath=com/google/code/gson/gson/2.1/gson-2.1.jar")) return false;
2014-04-04 20:55:21 +02:00
this . gson = this . getGsonBuilder ( ) . create ( ) ;
2014-07-01 22:10:18 +02:00
this . txt = new TextUtil ( ) ;
initTXT ( ) ;
2014-04-04 20:55:21 +02:00
// attempt to get first command defined in plugin.yml as reference command, if any commands are defined in there
// reference command will be used to prevent "unknown command" console messages
try {
Map < String , Map < String , Object > > refCmd = this . getDescription ( ) . getCommands ( ) ;
2014-07-01 22:10:18 +02:00
if ( refCmd ! = null & & ! refCmd . isEmpty ( ) ) {
this . refCommand = ( String ) ( refCmd . keySet ( ) . toArray ( ) [ 0 ] ) ;
}
2014-04-04 20:55:21 +02:00
} catch ( ClassCastException ex ) {
}
// Create and register listeners
this . mPluginSecretPlayerListener = new MPluginSecretPlayerListener ( this ) ;
this . mPluginSecretServerListener = new MPluginSecretServerListener ( this ) ;
getServer ( ) . getPluginManager ( ) . registerEvents ( this . mPluginSecretPlayerListener , this ) ;
getServer ( ) . getPluginManager ( ) . registerEvents ( this . mPluginSecretServerListener , this ) ;
// Register recurring tasks
if ( saveTask = = null & & Conf . saveToFileEveryXMinutes > 0 . 0 ) {
long saveTicks = ( long ) ( 20 * 60 * Conf . saveToFileEveryXMinutes ) ; // Approximately every 30 min by default
saveTask = Bukkit . getServer ( ) . getScheduler ( ) . scheduleSyncRepeatingTask ( this , new SaveTask ( this ) , saveTicks , saveTicks ) ;
}
2014-07-01 20:19:36 +02:00
loadLang ( ) ;
2014-07-01 22:10:18 +02:00
loadSuccessful = true ;
return true ;
2014-04-04 20:55:21 +02:00
}
public void postEnable ( ) {
log ( " === ENABLE DONE (Took " + ( System . currentTimeMillis ( ) - timeEnableStart ) + " ms) === " ) ;
}
2014-12-11 16:16:12 +01:00
public void loadLang ( ) {
2014-07-01 22:10:18 +02:00
File lang = new File ( getDataFolder ( ) , " lang.yml " ) ;
OutputStream out = null ;
InputStream defLangStream = this . getResource ( " lang.yml " ) ;
if ( ! lang . exists ( ) ) {
2014-07-01 20:19:36 +02:00
try {
2014-07-01 22:10:18 +02:00
getDataFolder ( ) . mkdir ( ) ;
lang . createNewFile ( ) ;
if ( defLangStream ! = null ) {
out = new FileOutputStream ( lang ) ;
int read ;
byte [ ] bytes = new byte [ 1024 ] ;
2014-07-01 20:19:36 +02:00
while ( ( read = defLangStream . read ( bytes ) ) ! = - 1 ) {
out . write ( bytes , 0 , read ) ;
2014-07-01 22:10:18 +02:00
}
YamlConfiguration defConfig = YamlConfiguration . loadConfiguration ( defLangStream ) ;
TL . setFile ( defConfig ) ;
2014-07-01 20:19:36 +02:00
}
} catch ( IOException e ) {
e . printStackTrace ( ) ; // So they notice
getLogger ( ) . severe ( " [Factions] Couldn't create language file. " ) ;
getLogger ( ) . severe ( " [Factions] This is a fatal error. Now disabling " ) ;
this . setEnabled ( false ) ; // Without it loaded, we can't send them messages
} finally {
if ( defLangStream ! = null ) {
try {
defLangStream . close ( ) ;
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
2014-07-01 22:10:18 +02:00
}
if ( out ! = null ) {
2014-07-01 20:19:36 +02:00
try {
out . close ( ) ;
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
}
}
}
2014-07-01 22:10:18 +02:00
YamlConfiguration conf = YamlConfiguration . loadConfiguration ( lang ) ;
for ( TL item : TL . values ( ) ) {
2014-07-01 20:19:36 +02:00
if ( conf . getString ( item . getPath ( ) ) = = null ) {
conf . set ( item . getPath ( ) , item . getDefault ( ) ) ;
}
}
2015-05-03 04:03:12 +02:00
// Remove this here because I'm sick of dealing with bug reports due to bad decisions on my part.
if ( conf . getString ( TL . COMMAND_SHOW_POWER . getPath ( ) , " " ) . contains ( " %5$s " ) ) {
conf . set ( TL . COMMAND_SHOW_POWER . getPath ( ) , TL . COMMAND_SHOW_POWER . getDefault ( ) ) ;
log ( Level . INFO , " Removed errant format specifier from f show power. " ) ;
}
2014-07-01 22:10:18 +02:00
TL . setFile ( conf ) ;
try {
2014-07-01 20:19:36 +02:00
conf . save ( lang ) ;
} catch ( IOException e ) {
getLogger ( ) . log ( Level . WARNING , " Factions: Failed to save lang.yml. " ) ;
2014-07-01 22:10:18 +02:00
getLogger ( ) . log ( Level . WARNING , " Factions: Report this stack trace to drtshock. " ) ;
e . printStackTrace ( ) ;
2014-07-01 20:19:36 +02:00
}
}
2014-04-04 20:55:21 +02:00
public void onDisable ( ) {
if ( saveTask ! = null ) {
2014-07-01 22:10:18 +02:00
this . getServer ( ) . getScheduler ( ) . cancelTask ( saveTask ) ;
saveTask = null ;
2014-04-04 20:55:21 +02:00
}
// only save data if plugin actually loaded successfully
2014-07-01 22:10:18 +02:00
if ( loadSuccessful ) {
2014-10-19 07:37:25 +02:00
Factions . getInstance ( ) . forceSave ( ) ;
FPlayers . getInstance ( ) . forceSave ( ) ;
Board . getInstance ( ) . forceSave ( ) ;
2014-07-01 22:10:18 +02:00
}
log ( " Disabled " ) ;
2014-04-04 20:55:21 +02:00
}
public void suicide ( ) {
2014-07-01 22:10:18 +02:00
log ( " Now I suicide! " ) ;
this . getServer ( ) . getPluginManager ( ) . disablePlugin ( this ) ;
2014-04-04 20:55:21 +02:00
}
// -------------------------------------------- //
// Some inits...
// You are supposed to override these in the plugin if you aren't satisfied with the defaults
// The goal is that you always will be satisfied though.
// -------------------------------------------- //
public GsonBuilder getGsonBuilder ( ) {
2014-07-01 21:52:40 +02:00
return new GsonBuilder ( ) . setPrettyPrinting ( ) . disableHtmlEscaping ( ) . serializeNulls ( ) . excludeFieldsWithModifiers ( Modifier . TRANSIENT , Modifier . VOLATILE ) ;
2014-04-04 20:55:21 +02:00
}
// -------------------------------------------- //
// LANG AND TAGS
// -------------------------------------------- //
// These are not supposed to be used directly.
// They are loaded and used through the TextUtil instance for the plugin.
public Map < String , String > rawTags = new LinkedHashMap < String , String > ( ) ;
public void addRawTags ( ) {
this . rawTags . put ( " l " , " <green> " ) ; // logo
this . rawTags . put ( " a " , " <gold> " ) ; // art
this . rawTags . put ( " n " , " <silver> " ) ; // notice
this . rawTags . put ( " i " , " <yellow> " ) ; // info
this . rawTags . put ( " g " , " <lime> " ) ; // good
this . rawTags . put ( " b " , " <rose> " ) ; // bad
this . rawTags . put ( " h " , " <pink> " ) ; // highligh
this . rawTags . put ( " c " , " <aqua> " ) ; // command
this . rawTags . put ( " p " , " <teal> " ) ; // parameter
}
public void initTXT ( ) {
this . addRawTags ( ) ;
2014-07-01 22:10:18 +02:00
Type type = new TypeToken < Map < String , String > > ( ) {
} . getType ( ) ;
2014-04-04 20:55:21 +02:00
Map < String , String > tagsFromFile = this . persist . load ( type , " tags " ) ;
2014-07-01 22:10:18 +02:00
if ( tagsFromFile ! = null ) {
this . rawTags . putAll ( tagsFromFile ) ;
}
this . persist . save ( this . rawTags , " tags " ) ;
2014-04-04 20:55:21 +02:00
for ( Entry < String , String > rawTag : this . rawTags . entrySet ( ) ) {
this . txt . tags . put ( rawTag . getKey ( ) , TextUtil . parseColor ( rawTag . getValue ( ) ) ) ;
}
}
// -------------------------------------------- //
// COMMAND HANDLING
// -------------------------------------------- //
// can be overridden by P method, to provide option
public boolean logPlayerCommands ( ) {
return true ;
}
public boolean handleCommand ( CommandSender sender , String commandString , boolean testOnly ) {
return handleCommand ( sender , commandString , testOnly , false ) ;
}
public boolean handleCommand ( final CommandSender sender , String commandString , boolean testOnly , boolean async ) {
2014-07-01 22:10:18 +02:00
boolean noSlash = true ;
if ( commandString . startsWith ( " / " ) ) {
noSlash = false ;
commandString = commandString . substring ( 1 ) ;
2014-04-04 20:55:21 +02:00
}
for ( final MCommand < ? > command : this . getBaseCommands ( ) ) {
2014-07-01 22:10:18 +02:00
if ( noSlash & & ! command . allowNoSlashAccess ) {
continue ;
}
2014-04-04 20:55:21 +02:00
for ( String alias : command . aliases ) {
// disallow double-space after alias, so specific commands can be prevented (preventing "f home" won't prevent "f home")
2014-07-01 22:10:18 +02:00
if ( commandString . startsWith ( alias + " " ) ) {
return false ;
}
2014-04-04 20:55:21 +02:00
if ( commandString . startsWith ( alias + " " ) | | commandString . equals ( alias ) ) {
final List < String > args = new ArrayList < String > ( Arrays . asList ( commandString . split ( " \\ s+ " ) ) ) ;
args . remove ( 0 ) ;
2014-07-01 22:10:18 +02:00
if ( testOnly ) {
return true ;
}
2014-04-04 20:55:21 +02:00
if ( async ) {
Bukkit . getServer ( ) . getScheduler ( ) . scheduleSyncDelayedTask ( this , new Runnable ( ) {
@Override
public void run ( ) {
command . execute ( sender , args ) ;
}
} ) ;
2014-07-01 22:10:18 +02:00
} else {
command . execute ( sender , args ) ;
}
2014-04-04 20:55:21 +02:00
return true ;
}
}
2014-07-01 22:10:18 +02:00
}
return false ;
2014-04-04 20:55:21 +02:00
}
public boolean handleCommand ( CommandSender sender , String commandString ) {
return this . handleCommand ( sender , commandString , false ) ;
}
// -------------------------------------------- //
// HOOKS
// -------------------------------------------- //
public void preAutoSave ( ) {
}
public void postAutoSave ( ) {
}
2015-05-13 05:16:47 +02:00
public Map < UUID , Integer > getStuckMap ( ) {
return this . stuckMap ;
}
public Map < UUID , Long > getTimers ( ) {
return this . timers ;
}
2014-04-04 20:55:21 +02:00
// -------------------------------------------- //
// LOGGING
// -------------------------------------------- //
public void log ( Object msg ) {
log ( Level . INFO , msg ) ;
}
public void log ( String str , Object . . . args ) {
log ( Level . INFO , this . txt . parse ( str , args ) ) ;
}
public void log ( Level level , String str , Object . . . args ) {
log ( level , this . txt . parse ( str , args ) ) ;
}
public void log ( Level level , Object msg ) {
Bukkit . getLogger ( ) . log ( level , " [ " + this . getDescription ( ) . getFullName ( ) + " ] " + msg ) ;
}
2011-10-08 22:03:44 +02:00
}