initial commit

This commit is contained in:
Bea 2020-04-09 18:21:05 +02:00
commit 4005f2d968
38 changed files with 1777 additions and 0 deletions

9
.idea/ant.xml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AntConfiguration">
<buildFile url="file://$PROJECT_DIR$/ant_build_increment.xml">
<executeOn event="afterCompilation" target="end" />
<executeOn event="beforeCompilation" target="init" />
</buildFile>
</component>
</project>

View File

@ -0,0 +1,9 @@
<component name="ArtifactManager">
<artifact type="jar" name="Spigot Complete Plugin (Debugger, Listener, CommandExecutor):jar">
<output-path>D:/Coding/# Server per Test Plugins #/plugins</output-path>
<root id="archive" name="lasergun.jar">
<element id="module-output" name="LaserGun" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/annotations/17.0.0/annotations-17.0.0.jar" path-in-jar="/" />
</root>
</artifact>
</component>

0
.idea/description.html Normal file
View File

View File

@ -0,0 +1,11 @@
<component name="ProjectDictionaryState">
<dictionary name="Lorenzo">
<words>
<w>bukkit</w>
<w>bungeecord</w>
<w>lasergun</w>
<w>textcomponent</w>
<w>yamls</w>
</words>
</dictionary>
</component>

6
.idea/encodings.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

6
.idea/misc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/LaserGun.iml" filepath="$PROJECT_DIR$/LaserGun.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,3 @@
<template>
<input-field default="net.mindoverflow.pluginpackage">IJ_BASE_PACKAGE</input-field>
</template>

5
.idea/template-meta.xml Normal file
View File

@ -0,0 +1,5 @@
<template unencoded="false">
<roots>
<root index="0" path="" />
</roots>
</template>

124
.idea/uiDesigner.xml Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

80
.idea/workspace.xml Normal file
View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ArtifactsWorkspaceSettings">
<artifacts-to-build>
<artifact name="Spigot Complete Plugin (Debugger, Listener, CommandExecutor):jar" />
</artifacts-to-build>
</component>
<component name="ChangeListManager">
<list default="true" id="89416e2e-2c77-406b-b1ba-832a73db08e5" name="Default Changelist" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Class" />
</list>
</option>
</component>
<component name="ProjectId" id="1WtCBtrdbQ7L1kO8DRxBrBxDqoC" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showExcludedFiles" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="GenerateAntBuildDialog.backupFiles" value="true" />
<property name="GenerateAntBuildDialog.enableUiFormCompile" value="true" />
<property name="GenerateAntBuildDialog.forceTargetJdk" value="true" />
<property name="GenerateAntBuildDialog.outputFileNameProperty" value="lasergun" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/../../../spigot-1.14.4.jar!/" />
<property name="project.structure.last.edited" value="Modules" />
<property name="project.structure.proportion" value="0.15" />
<property name="project.structure.side.proportion" value="0.2" />
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="89416e2e-2c77-406b-b1ba-832a73db08e5" name="Default Changelist" comment="" />
<created>1579959371190</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1579959371190</updated>
</task>
<servers />
</component>
<component name="WindowStateProjectService">
<state x="873" y="359" key="#Project_Structure" timestamp="1584407966734">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="873" y="359" key="#Project_Structure/0.0.2560.1400/3840.1065.1600.860@0.0.2560.1400" timestamp="1579970197122" />
<state x="873" y="359" key="#Project_Structure/3840.1065.1600.840/-1360.1191.1360.728/0.0.2560.1400@0.0.2560.1400" timestamp="1584407966734" />
<state x="1086" y="404" key="#com.intellij.ide.util.MemberChooser" timestamp="1579975786283">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="1086" y="404" key="#com.intellij.ide.util.MemberChooser/0.0.2560.1400/3840.1065.1600.860@0.0.2560.1400" timestamp="1579975786283" />
<state x="721" y="0" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog" timestamp="1579959743873">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="721" y="0" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog/0.0.2560.1400/3840.1065.1600.860@0.0.2560.1400" timestamp="1579959743873" />
<state x="1011" y="446" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog" timestamp="1580576147910">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="1011" y="446" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog/0.0.2560.1400/3840.1065.1600.860@0.0.2560.1400" timestamp="1579973457686" />
<state x="1011" y="446" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog/3840.1065.1600.840/-1360.1191.1360.728/0.0.2560.1400@0.0.2560.1400" timestamp="1580576147910" />
<state x="1035" y="403" key="DetectedRootsChooserDialog" timestamp="1584407120941">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="1035" y="403" key="DetectedRootsChooserDialog/3840.1065.1600.840/-1360.1191.1360.728/0.0.2560.1400@0.0.2560.1400" timestamp="1584407120941" />
<state x="967" y="441" key="FileChooserDialogImpl" timestamp="1584407941660">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="967" y="441" key="FileChooserDialogImpl/0.0.2560.1400/3840.1065.1600.860@0.0.2560.1400" timestamp="1579972638166" />
<state x="967" y="441" key="FileChooserDialogImpl/3840.1065.1600.840/-1360.1191.1360.728/0.0.2560.1400@0.0.2560.1400" timestamp="1584407941660" />
</component>
</project>

40
LaserGun.iml Normal file
View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/17.0.0/annotations-17.0.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="PROVIDED">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../../ProtocolLib.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="PROVIDED">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../../spigot-1.14.4.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/../../../spigot-1.14.4.jar!/" />
</SOURCES>
</library>
</orderEntry>
</component>
</module>

38
ant_build_increment.xml Normal file
View File

@ -0,0 +1,38 @@
<project name="BuildIncrement" default="init" basedir=".">
<description>
simple example increment build variable
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="version" value="0.0"/>
<loadproperties>
<file file="build.number"/>
</loadproperties>
<target name="init">
<echo file="ant_buildversion_init.txt">Changing build version from BUILD_VERSION to ${version}.${build.number} in file plugin.yml...</echo>
<replaceregexp file="${src}/plugin.yml"
match="BUILD_NUMBER"
replace="${version}.${build.number}"
byline="true"
/>
<echo file="ant_buildversion_init.txt">Changed!</echo>
</target>
<target name="end">
<echo file="ant_buildversion_end.txt">Changing back build version ${version}.${build.number} in file plugin.yml to BUILD_VERSION...</echo>
<replaceregexp file="${src}/plugin.yml"
match="${version}.${build.number}"
replace="BUILD_NUMBER"
byline="true"
/>
<buildnumber/>
<echo file="ant_buildversion_init.txt">Changed!</echo>
</target>
</project>

1
ant_buildversion_end.txt Normal file
View File

@ -0,0 +1 @@
Changing back build version 0.0.153 in file plugin.yml to BUILD_VERSION...

View File

@ -0,0 +1 @@
Changed!

5
build.number Normal file
View File

@ -0,0 +1,5 @@
#Build Number for ANT. Do not edit!
#Tue Mar 17 02:22:36 CET 2020
\#Build=Number for ANT. Do not edit\!
build.number=154
\#Tue=Jul 30 16\:09\:09 CEST 2019

4
src/config.yml Normal file
View File

@ -0,0 +1,4 @@
radius: 10
damage: 6.0
sound: true
update-checker: true

6
src/lang.yml Normal file
View File

@ -0,0 +1,6 @@
error:
console_access_blocked: '&cSorry, but this command is not available via console.'
no_permissions: '&cYou do not have permissions!'
info:
lasergun_name: '&6&lLaser Gun'
lasergun_lore: '&eUse this gun to shoot other players!'

View File

@ -0,0 +1,124 @@
package net.mindoverflow.lasergun;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import net.mindoverflow.lasergun.commands.LaserGunCommand;
import net.mindoverflow.lasergun.completers.InfoCompleter;
import net.mindoverflow.lasergun.listeners.*;
import net.mindoverflow.lasergun.utils.Debugger;
import net.mindoverflow.lasergun.utils.FileUtils;
import net.mindoverflow.lasergun.utils.MessageUtils;
import net.mindoverflow.lasergun.utils.stats.UpdateChecker;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class LaserGun extends JavaPlugin
{
// Instantiate a Debugger for this class.
private Debugger debugger = new Debugger(getClass().getName());
// Initializing needed variables.
public static Logger logger;
private PluginManager pluginManager;
public ProtocolManager protocolManager;
public UpdateChecker updateChecker;
// Method called when the plugin is being loaded.
@Override
public void onEnable()
{
// Give the initialized variables their respective values. Absolutely don't do this before as they will look good in the IDE but will result null.
logger = getLogger();
pluginManager = getServer().getPluginManager();
// Check and report if the Debugger is enabled (the method itself does the checking). Would do it before but we need the logger to be initialized! :(
debugger.sendDebugMessage(Level.WARNING, "---[ DEBUGGER IS ENABLED! ]---");
debugger.sendDebugMessage(Level.WARNING, "---[ INITIALIZING PLUGIN ]---");
debugger.sendDebugMessage(Level.INFO, "Logger and PluginManager already initialized.");
// Register instances and give them the plugin parameter (this, because this class is the JavaPlugin) so they can access all of its info.
debugger.sendDebugMessage(Level.INFO, "Instantiating some classes that need to access to plugin data...");
FileUtils fileUtilsInstance = new FileUtils(this);
PlayerJoinListener playerJoinListenerInstance = new PlayerJoinListener(this);
LaserGunCommand laserGunCommandInstance = new LaserGunCommand(this);
MessageUtils messageUtils = new MessageUtils(this);
updateChecker = new UpdateChecker(this);
debugger.sendDebugMessage(Level.INFO, "Done instantiating classes!");
// Register Listeners
debugger.sendDebugMessage(Level.INFO, "Registering listeners...");
pluginManager.registerEvents(playerJoinListenerInstance, this);
pluginManager.registerEvents(new PlayerInteractListener(this), this);
pluginManager.registerEvents(new ArrowDamageListener(this), this);
pluginManager.registerEvents(new ArrowHitListener(), this);
debugger.sendDebugMessage(Level.INFO, "Done registering listeners!");
// Register Commands
debugger.sendDebugMessage(Level.INFO, "Registering commands...");
getCommand("lasergun").setExecutor(laserGunCommandInstance);
getCommand("lasergun").setTabCompleter(new InfoCompleter());
debugger.sendDebugMessage(Level.INFO, "Done registering commands!");
// Check if all needed files exist and work correctly, also loading their YAMLs.
debugger.sendDebugMessage(Level.INFO, "Checking files...");
FileUtils.checkFiles();
debugger.sendDebugMessage(Level.INFO, "Done checking files!");
/*
Load all the YAML files. We are already loading them in FileUtils's checkFiles() method but we are loading them singularly.
With this method we are sure that all the files get successfully loaded. Better twice than never...
*/
debugger.sendDebugMessage(Level.INFO, "Reloading YAML config...");
FileUtils.reloadYamls();
debugger.sendDebugMessage(Level.INFO, "Done!");
// Loading ProtocolManager
debugger.sendDebugMessage(Level.INFO, "Loading ProtocolManager...!");
if(pluginManager.getPlugin("ProtocolLib") == null)
{
getServer().getScheduler().runTask(this, () ->
{
CommandSender console = getServer().getConsoleSender();
String pluginName = getName();
MessageUtils.sendColorizedMessage(console, pluginName + ": &c-------------[ &4" + pluginName + "&c ]-------------");
MessageUtils.sendColorizedMessage(console, pluginName + ": &cWARNING! This plugin needs ProtocolLib to work correctly.");
MessageUtils.sendColorizedMessage(console, pluginName + ": &cThe plugin will now be disabled.");
MessageUtils.sendColorizedMessage(console, pluginName + ": &cDownload ProtocolLib at: &nhttp://bit.ly/38PMAy3");
pluginManager.disablePlugin(this);
});
return;
}
protocolManager = ProtocolLibrary.getProtocolManager();
debugger.sendDebugMessage(Level.INFO, "Done!");
// Send success output message to console.
logger.log(Level.INFO, "Plugin " + getDescription().getName() + " Successfully Loaded!");
debugger.sendDebugMessage(Level.WARNING, "---[ INITIALIZATION DONE ]---");
}
// Method called when the plugin is being unloaded.
@Override
public void onDisable() {
debugger.sendDebugMessage(Level.WARNING, "---[ DEBUGGER IS ENABLED! ]---");
debugger.sendDebugMessage(Level.WARNING, "---[ DISABLING PLUGIN ]---");
logger.log(Level.INFO, "Plugin " + getDescription().getName() + " Successfully Unloaded!");
debugger.sendDebugMessage(Level.WARNING, "---[ PLUGIN DISABLED ]---");
}
}

View File

@ -0,0 +1,79 @@
package net.mindoverflow.lasergun.commands;
import net.mindoverflow.lasergun.LaserGun;
import net.mindoverflow.lasergun.commands.laserguncommands.GetCommand;
import net.mindoverflow.lasergun.commands.laserguncommands.HelpCommand;
import net.mindoverflow.lasergun.commands.laserguncommands.ReloadCommand;
import net.mindoverflow.lasergun.utils.Debugger;
import net.mindoverflow.lasergun.utils.MessageUtils;
import net.mindoverflow.lasergun.utils.LocalizedMessages;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import java.util.logging.Level;
public class LaserGunCommand implements CommandExecutor
{
// Initialize the plugin variable so we can access all of the plugin's data.
private LaserGun plugin;
// Initialize the debugger so I can debug the plugin.
private Debugger debugger = new Debugger(getClass().getName());
// Constructor to actually give "plugin" a value.
public LaserGunCommand(LaserGun givenPlugin)
{
plugin = givenPlugin;
}
// Override the default command. Set the instructions for this particular command (registered in the main class).
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args)
{
// Log who is using the command.
debugger.sendDebugMessage(Level.INFO, "Sender is instance of: " + commandSender.getClass().getName());
// If the command comes from Console, give a warning.
boolean senderIsConsole = !(commandSender instanceof Player);
// Check if there are any args.
if(args.length == 0)
{
MessageUtils.sendColorizedMessage(commandSender, "&7" + plugin.getName() + " version &6" + plugin.getDescription().getVersion());
MessageUtils.sendColorizedMessage(commandSender, "&7Coded by &6mind_overflow&7, all rights reserved (&6Copyright © '20&7).");
commandSender.sendMessage("");
MessageUtils.sendColorizedMessage(commandSender, "&7Write &6/" + plugin.getName().toLowerCase() + " help&7 to see plugin commands.");
}
// Check if there is a single argument after the command itself.
else if (args.length == 1)
{
// Check if the args are "help" and send help message.
if(args[0].equalsIgnoreCase("help")) {
HelpCommand.infoCommand(commandSender, plugin);
}
// Check if the args are "reload" and in case, do it.
else if(args[0].equalsIgnoreCase("reload"))
{
ReloadCommand.reloadCommand(commandSender, plugin);
}
// Check if the args are "textcomponent" and run that command.
else if (args[0].equalsIgnoreCase("get"))
{
// We do not want the console to receive the item, so we're gonna disable it.
if(senderIsConsole)
{
MessageUtils.sendLocalizedMessage(commandSender, LocalizedMessages.ERROR_CONSOLE_ACCESS_BLOCKED);
return true;
}
GetCommand.getCommand((Player)commandSender);
}
}
return true;
}
}

View File

@ -0,0 +1,51 @@
package net.mindoverflow.lasergun.commands.laserguncommands;
import net.mindoverflow.lasergun.utils.LocalizedMessages;
import net.mindoverflow.lasergun.utils.MessageUtils;
import net.mindoverflow.lasergun.utils.PermissionUtils;
import net.mindoverflow.lasergun.utils.Permissions;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
public class GetCommand
{
public static void getCommand(Player player)
{
if(!PermissionUtils.playerHasPermission(player, Permissions.ITEM_GET))
{
MessageUtils.sendLocalizedMessage(player, LocalizedMessages.ERROR_NO_PERMISSIONS);
return;
}
/*Material itemMat;
if(Material.getMaterial("REPEATER") != null)
{
itemMat = Material.getMaterial("REPEATER");
}
else
{
itemMat = Material.getMaterial("REDSTONE_COMPARATOR");
}*/
// Material itemMat = Material.REDSTONE_COMPARATOR; LEGACY!
Material itemMat = Material.REPEATER;
ItemStack lasergunItem = new ItemStack(itemMat);
ItemMeta lasergunIM = lasergunItem.getItemMeta();
lasergunIM.setDisplayName(MessageUtils.getLocalizedMessage(LocalizedMessages.LASERGUN_NAME, true));
ArrayList<String>lore = new ArrayList<String>();
lore.add(MessageUtils.getLocalizedMessage(LocalizedMessages.LASERGUN_LORE, true));
lasergunIM.setLore(lore);
lasergunItem.setItemMeta(lasergunIM);
player.getInventory().addItem(lasergunItem);
}
}

View File

@ -0,0 +1,24 @@
package net.mindoverflow.lasergun.commands.laserguncommands;
import net.mindoverflow.lasergun.LaserGun;
import net.mindoverflow.lasergun.utils.ConfigEntries;
import net.mindoverflow.lasergun.utils.FileUtils;
import net.mindoverflow.lasergun.utils.LocalizedMessages;
import net.mindoverflow.lasergun.utils.MessageUtils;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class HelpCommand
{
public static void infoCommand(CommandSender commandSender, LaserGun plugin)
{
String cmdName = "&e/" + plugin.getName().toLowerCase();
commandSender.sendMessage(MessageUtils.colorize("&7---------[&c " + plugin.getName() + " " + plugin.getDescription().getVersion() + " &7]---------"));
commandSender.sendMessage(MessageUtils.colorize(cmdName + " help&7: see this help page"));
commandSender.sendMessage(MessageUtils.colorize(cmdName + " get&7: get the Laser Gun&8 - lasergun.getgun"));
commandSender.sendMessage(MessageUtils.colorize(cmdName + " reload&7: reload the config&8 - lasergun.reload"));
}
}

View File

@ -0,0 +1,33 @@
package net.mindoverflow.lasergun.commands.laserguncommands;
import net.mindoverflow.lasergun.LaserGun;
import net.mindoverflow.lasergun.utils.*;
import org.bukkit.command.CommandSender;
import java.util.logging.Level;
public class ReloadCommand
{
private static Debugger debugger = new Debugger(ReloadCommand.class.getName());
public static void reloadCommand(CommandSender commandSender, LaserGun plugin)
{
if(!PermissionUtils.playerHasPermission(commandSender, Permissions.COMMAND_RELOAD))
{
MessageUtils.sendLocalizedMessage(commandSender, LocalizedMessages.ERROR_NO_PERMISSIONS);
return;
}
debugger.sendDebugMessage(Level.INFO, "Reloading YAMLS...");
MessageUtils.sendColorizedMessage(commandSender, "&7Reloading &e" + plugin.getName() + "&7 v.&e" + plugin.getDescription().getVersion() + "&7...");
FileUtils.checkFiles();
FileUtils.reloadYamls();
MessageUtils.sendColorizedMessage(commandSender, "&eReloaded!");
debugger.sendDebugMessage(Level.INFO, "Reloaded YAMLs!");
// This method checks if player has permissions, checks error codes, and acts accordingly.
plugin.updateChecker.playerMessage(commandSender);
}
}

View File

@ -0,0 +1,38 @@
package net.mindoverflow.lasergun.completers;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import java.util.ArrayList;
import java.util.List;
public class InfoCompleter implements TabCompleter {
@Override
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] args)
{
List<String> list = new ArrayList<String>();
if(args.length == 1)
{
list.add("help");
list.add("get");
list.add("reload");
if(args[0].startsWith("h"))
{
list.clear();
list.add("help");
} else
if(args[0].startsWith("g"))
{
list.clear();
list.add("get");
} else
if(args[0].startsWith("r"))
{
list.clear();
list.add("reload");
}
}
return list;
}
}

View File

@ -0,0 +1,76 @@
package net.mindoverflow.lasergun.listeners;
import net.mindoverflow.lasergun.LaserGun;
import net.mindoverflow.lasergun.utils.ConfigEntries;
import net.mindoverflow.lasergun.utils.Debugger;
import net.mindoverflow.lasergun.utils.FileUtils;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.Objects;
import java.util.logging.Level;
public class ArrowDamageListener implements Listener
{
Debugger debugger = new Debugger(getClass().getName());
private LaserGun plugin;
public ArrowDamageListener(LaserGun givenPlugin)
{
plugin = givenPlugin;
}
@EventHandler
public void onEntityDamage(EntityDamageByEntityEvent event)
{
debugger.sendDebugMessage(Level.INFO, "Arrow damage!");
debugger.sendDebugMessage(Level.INFO, "ID: " + event.getDamager().getEntityId());
if(PlayerInteractListener.spawnedArrowsLocations.containsKey(event.getDamager().getEntityId()))
{
debugger.sendDebugMessage(Level.INFO, "Arrow is in list! ID: " + event.getDamager().getEntityId());
Location currentLoc = event.getEntity().getLocation();
Location spawnLoc = PlayerInteractListener.spawnedArrowsLocations.get(event.getDamager().getEntityId());
debugger.sendDebugMessage(Level.INFO, "Dist: " + currentLoc.distance(spawnLoc));
debugger.sendDebugMessage(Level.INFO, "Arrow loc: " + currentLoc);
// Load the radius.
int radius = FileUtils.FileType.CONFIG_YAML.yaml.getInt(ConfigEntries.RADIUS.path);
if(currentLoc.distance(spawnLoc) > radius)
{
//debugger.sendDebugMessage(Level.INFO, "Radius too big!");
event.setDamage(0.0);
event.setCancelled(true);
} else
{
// Set the arrow damage.
double damage = FileUtils.FileType.CONFIG_YAML.yaml.getInt(ConfigEntries.DAMAGE.path);
event.setDamage(damage);
// Play a "hit" sound.
Objects.requireNonNull(currentLoc.getWorld()).playSound(currentLoc, Sound.ENTITY_GENERIC_HURT, 1, 1);
//Objects.requireNonNull(currentLoc.getWorld()).playSound(currentLoc, Sound.HURT_FLESH, 1, 1); LEGACY!
}
PlayerInteractListener.spawnedArrowsLocations.remove(event.getDamager().getEntityId());
debugger.sendDebugMessage(Level.INFO, "Removed from list!");
new BukkitRunnable(){
@Override
public void run(){
event.getDamager().remove();
debugger.sendDebugMessage(Level.INFO, "Removed entity!");
}
}.runTaskLater(plugin, 1);
}
}
}

View File

@ -0,0 +1,23 @@
package net.mindoverflow.lasergun.listeners;
import net.mindoverflow.lasergun.utils.Debugger;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileHitEvent;
import java.util.logging.Level;
public class ArrowHitListener implements Listener
{
Debugger debugger = new Debugger(getClass().getName());
@EventHandler
public void onArrowJust(ProjectileHitEvent event)
{
debugger.sendDebugMessage(Level.INFO, "Entity type: " + event.getHitEntity());
if(event.getHitEntity() == null && PlayerInteractListener.spawnedArrowsLocations.containsKey(event.getEntity().getEntityId()))
{
PlayerInteractListener.spawnedArrowsLocations.remove(event.getEntity().getEntityId());
debugger.sendDebugMessage(Level.INFO, "Removed entity as it hit NULL!");
}
}
}

View File

@ -0,0 +1,151 @@
package net.mindoverflow.lasergun.listeners;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import net.mindoverflow.lasergun.LaserGun;
import net.mindoverflow.lasergun.utils.*;
import org.bukkit.*;
import org.bukkit.block.Block;
//import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.util.Vector;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.logging.Level;
public class PlayerInteractListener implements Listener
{
Debugger debugger = new Debugger(getClass().getName());
private LaserGun plugin;
public PlayerInteractListener(LaserGun givenPlugin)
{
plugin = givenPlugin;
}
public static HashMap<Integer, Location>spawnedArrowsLocations = new HashMap<>();
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event)
{
// Check if the player is right clicking.
if(event.getAction().equals(Action.RIGHT_CLICK_AIR) || event.getAction().equals(Action.RIGHT_CLICK_BLOCK))
{
// Initialize the player variable.
Player player = event.getPlayer();
// Load the gun name.
String gunName = MessageUtils.getLocalizedMessage(LocalizedMessages.LASERGUN_NAME, true);
// Check if the player is holding the laser gun.
if(player.getInventory().getItemInMainHand().hasItemMeta() && Objects.requireNonNull(player.getInventory().getItemInMainHand().getItemMeta()).getDisplayName().contains(gunName) ||
player.getInventory().getItemInOffHand().hasItemMeta() && Objects.requireNonNull(player.getInventory().getItemInOffHand().getItemMeta()).getDisplayName().contains(gunName))
{
/*if(player.getInventory().getItemInHand().hasItemMeta() && Objects.requireNonNull(player.getInventory().getItemInHand().getItemMeta()).getDisplayName().contains(gunName))
{*/
// Cancel the event.
event.setCancelled(true);
// Check if player does not have permissions to use the item and stop.
if(!PermissionUtils.playerHasPermission(player, Permissions.ITEM_USE))
{
MessageUtils.sendLocalizedMessage(player, LocalizedMessages.ERROR_NO_PERMISSIONS);
return;
}
// Load the player location and increase it by 1, so it's in the middle of his body.
Location playerLocation = player.getLocation();
playerLocation.setY(playerLocation.getY() + 1);
// Play a sound at the player location, if enabled.
if(FileUtils.FileType.CONFIG_YAML.yaml.getBoolean(ConfigEntries.SOUND.path))
{
Objects.requireNonNull(playerLocation.getWorld()).playSound(playerLocation, Sound.ENTITY_GHAST_SHOOT, (float)0.5, 2);
}
// Create a set of Materials we should be able to shoot through.
Set<Material> transparent = new HashSet<Material>();
transparent.add(Material.WATER);
transparent.add(Material.AIR);
transparent.add(Material.VOID_AIR);
transparent.add(Material.CAVE_AIR);
transparent.add(Material.GRASS);
transparent.add(Material.TALL_GRASS);
transparent.add(Material.BAMBOO);
// Load the target block location (with a max radius) and move it to the middle.
int radius = FileUtils.FileType.CONFIG_YAML.yaml.getInt(ConfigEntries.RADIUS.path);
Block targetBlock = player.getTargetBlock(transparent, radius);
Location targetLocation = targetBlock.getLocation();
targetLocation.setX(targetLocation.getX() + 0.5);
targetLocation.setY(targetLocation.getY() + 0.5);
targetLocation.setZ(targetLocation.getZ() + 0.5);
debugger.sendDebugMessage(Level.INFO, "Target block: " +targetBlock.getType());
// Create a vector from the player to the block.
Vector vector = getDirectionBetweenLocations(playerLocation, targetLocation);
//vector.multiply(-1); LEGACY!
// Spawn an arrow to damage entities.
//Arrow arrow = Objects.requireNonNull(playerLocation.getWorld()).spawnArrow(player.getEyeLocation(), vector, 100, 0); LEGACY!
Arrow arrow = Objects.requireNonNull(playerLocation.getWorld()).spawnArrow(player.getEyeLocation(), vector, 30, 0);
//vector.multiply(-1); LEGACY!
// Set the arrow name.
arrow.setCustomName("Laser Gun");
// Remove the arrow sound.
arrow.setSilent(true);
// Add the arrow to the spawned list.
spawnedArrowsLocations.put(arrow.getEntityId(), playerLocation);
debugger.sendDebugMessage(Level.INFO,"Player loc: " + playerLocation);
debugger.sendDebugMessage(Level.INFO, "Size: " + spawnedArrowsLocations.size() + ", put ID: " + spawnedArrowsLocations.get(arrow.getEntityId()) + ", ID: " + arrow.getEntityId());
// Disable arrow pickup.
arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED);
//arrow.setPickupStatus(Arrow.PickupStatus.DISALLOWED); LEGACY!
// hide the arrow to everyone using packets.
PacketContainer con = plugin.protocolManager.createPacket(PacketType.Play.Server.ENTITY_DESTROY);
int[]dest = {arrow.getEntityId()};
con.getIntegerArrays().write(0, dest);
try {
for(Player p : plugin.getServer().getOnlinePlayers())
{
plugin.protocolManager.sendServerPacket(p, con);
debugger.sendDebugMessage(Level.INFO, "Hidden arrow!");
}
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// Iterate through every vector position to draw the particles line.
for(double i = 1.0; i < playerLocation.distance(targetLocation); i += 0.1)
{
vector.multiply(i);
playerLocation.add(vector);
playerLocation.getWorld().spawnParticle(Particle.REDSTONE, playerLocation, 1, new Particle.DustOptions(Color.RED, 1));
//playerLocation.getWorld().spawnParticle(Particle.REDSTONE, playerLocation, 0, 255, 0, 0); LEGACY!
playerLocation.subtract(vector);
vector.normalize();
}
}
}
}
Vector getDirectionBetweenLocations(Location start, Location end) {
Vector from = start.toVector();
Vector to = end.toVector();
return to.subtract(from);
}
}

View File

@ -0,0 +1,37 @@
package net.mindoverflow.lasergun.listeners;
import net.mindoverflow.lasergun.LaserGun;
import net.mindoverflow.lasergun.utils.Debugger;
import net.mindoverflow.lasergun.utils.MessageUtils;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import java.util.logging.Level;
public class PlayerJoinListener implements Listener
{
// Instantiate a Debugger for this class.
private Debugger debugger = new Debugger(getClass().getName());
private LaserGun plugin;
public PlayerJoinListener(LaserGun givenPlugin)
{
plugin = givenPlugin;
}
// Call EventHandler and start listening to joining players.
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e)
{
// Initialize needed variables for performance improvements and to avoid continuous method calls.
Player player = e.getPlayer();
if(player.getName().equalsIgnoreCase(debugger.authorName) || player.getUniqueId().equals(debugger.authorUUID))
{
MessageUtils.sendColorizedMessage(player, "&7This server is running &3" + plugin.getName() + "&7 v&3" + plugin.getDescription().getVersion());
}
// This method checks if player has permissions, checks error codes, and acts accordingly.
plugin.updateChecker.playerMessage(player);
}
}

View File

@ -0,0 +1,7 @@
package net.mindoverflow.lasergun.utils;
public class CommonValues
{
public static boolean updateChecker;
}

View File

@ -0,0 +1,20 @@
package net.mindoverflow.lasergun.utils;
public enum ConfigEntries
{
//HELP("help");
RADIUS("radius"),
DAMAGE("damage"),
SOUND("sound"),
UPDATE_CHECKER("update-checker");
public String path;
ConfigEntries(String path)
{
this.path = path;
}
}

View File

@ -0,0 +1,87 @@
package net.mindoverflow.lasergun.utils;
import net.mindoverflow.lasergun.LaserGun;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.UUID;
import java.util.logging.Level;
public class Debugger
{
// Enable or disable debugging messages (aka verbosity).
private final boolean DEBUGGING = false;
// Initialize needed variables. We will need those variables to be able to precisely debug the plugin.
private String className;
private String packageName;
// Save my UUID and current Username somewhere so I can get debug messages too.
public UUID authorUUID = UUID.fromString("297a1dc8-c0a3-485a-ad21-8956c749f927");
public String authorName = "mind_overflow";
// Make a constructor requiring to be given a class so we exactly know which class has made an instance of it and all of its properties.
public Debugger(String instanceClassName)
{
// Only run this code and actually make a whole instance of the class only if debugging is active.
if(DEBUGGING)
{
// Initializing the class variable and set it to this one: in case something bad happens, we still have the log without the class info.
Class instanceClass = getClass();
try
{
/*
* Try finding the instancing class. This is normally bad for performance as we have to search for the class since we only have its name
* but the only other way would have been to always instantiate a whole class instead of a single String, making the plugin resource
* hungry even if the Debugger was disabled.
*/
instanceClass = Class.forName(instanceClassName);
}
catch (ClassNotFoundException e)
{
// In case it throws an error, go mad and report it in console.
LaserGun.logger.log(Level.INFO, "WTF? A class made an instance of the Debugger but it somehow can't define which class was it. Very weird. Setting it to the Debugger class.");
LaserGun.logger.log(Level.INFO, "Please send the following error log to me (" + authorName + "):");
e.printStackTrace();
}
// Give the instance's variables their respective values.
className = instanceClass.getSimpleName();
packageName = instanceClass.getPackage().getName();
}
}
/*
* Check if debugging is enabled and eventually send debug logs. No need to worry about some of this data being null as there already are
* checks and fixed for that in the constructor. Also, the debugger must be instanced for this method to be called (it's not static), so
* we already have the info we need thanks to that.
*/
public void sendDebugMessage(Level lvl, String str)
{
// Check if debugging is enabled.
if(DEBUGGING)
{
// Put together all the info we have in a single String.
String msg = className + ": " + str;
// Send the info to the server log.
LaserGun.logger.log(lvl, msg);
// Check if I'm online and if I am, send me the same info.
Player author = Bukkit.getPlayer(authorUUID);
if(author == null) {
author = Bukkit.getPlayer(authorName);
}
if(author != null)
{
if(Bukkit.getServer().getOnlinePlayers().contains(author))
{
author.sendMessage(msg);
}
}
}
}
}

View File

@ -0,0 +1,219 @@
package net.mindoverflow.lasergun.utils;
import net.mindoverflow.lasergun.LaserGun;
import net.mindoverflow.lasergun.utils.stats.UpdateChecker;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.logging.Level;
public class FileUtils
{
// Instantiate a Debugger for this class.
private static Debugger debugger = new Debugger(FileUtils.class.getName());
// Necessary variables.
private static LaserGun plugin;
public FileUtils(LaserGun plugin) {
FileUtils.plugin = plugin;
}
private static void copyFileFromSrc(FileType givenFileType)
{
// Check if files already exists and if it doesn't, then create it.
if(!givenFileType.file.exists())
{
// Load the InputStream of the file in the source folder.
InputStream is = FileUtils.class.getResourceAsStream("/" + givenFileType.file.getName());
try
{
// Try copying the file to the directory where it's supposed to be, and log it.
Files.copy(is, Paths.get(givenFileType.file.getAbsolutePath()));
is.close();
debugger.sendDebugMessage(Level.INFO, "File " + givenFileType.file.getName() + " successfully created.");
}
catch (IOException e)
{
// Throw exception if something went wrong (lol, I expect this to happen since we're working with files in different systems)
LaserGun.logger.log(Level.SEVERE, "There were some unexpected errors from " + givenFileType.file.getName() + " file creation. Please contact the developer and send him this log:");
e.printStackTrace();
}
}
}
// As method says, reload YamlConfigurations by overwriting their previous value.
public static void reloadYamls()
{
FileType.CONFIG_YAML.yaml = YamlConfiguration.loadConfiguration(FileType.CONFIG_YAML.file);
FileType.LANG_YAML.yaml = YamlConfiguration.loadConfiguration(FileType.LANG_YAML.file);
YamlConfiguration config = FileType.CONFIG_YAML.yaml;
CommonValues.updateChecker = config.getBoolean(ConfigEntries.UPDATE_CHECKER.path);
if(UpdateChecker.task != null) plugin.getServer().getScheduler().cancelTask(UpdateChecker.task.getTaskId());
if(CommonValues.updateChecker) UpdateChecker.task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, plugin.updateChecker, 1, 20 * 60 * 60 * 12);
}
// Only reload the needed File.
public static void reloadYaml(FileType yamlFile)
{
yamlFile.yaml = YamlConfiguration.loadConfiguration(yamlFile.file);
debugger.sendDebugMessage(Level.INFO, "File " + yamlFile.file.getName() + " YAML loaded.");
}
// Save a Yaml file from the list of the plugin's YamlFiles enum.
public static void saveExistingYaml(FileType yamlFile)
{
// Get the actual File and its location.
File configFile = yamlFile.file;
try {
// Try saving the value in FileType.NAME.yaml into the file itself we just got. Else, it would only be saved in RAM and then be lost after unloading the plugin.
yamlFile.yaml.save(configFile);
debugger.sendDebugMessage(Level.INFO, "Successfully saved " + configFile.getName() +" (YAML)!");
} catch (IOException e) {
debugger.sendDebugMessage(Level.SEVERE, "Error in saving " + configFile.getName() + "(YAML)!");
e.printStackTrace();
}
// Reload the Yaml configuration from the file, just in case.
reloadYaml(yamlFile);
}
// Check if all needed files exist and work correctly.
public static void checkFiles() {
// Check if the different needed files and folders exist and if not, try creating them.
// Check if plugin folder exists and eventually make it. Easy enough.
if(!plugin.getDataFolder().exists())
{
if(plugin.getDataFolder().mkdir())
{
debugger.sendDebugMessage(Level.INFO, "Plugin dir successfully created.");
}
}
// Check and eventually create config file.
copyFileFromSrc(FileType.CONFIG_YAML);
// Reload file YAML data into FileType.NAME.yaml.
reloadYaml(FileType.CONFIG_YAML);
// Check if there is any missing entry.
checkYamlMissingEntries(FileType.CONFIG_YAML);
// Check and eventually create players file.
copyFileFromSrc(FileType.LANG_YAML);
// Reload file YAML data into FileType.NAME.yaml.
reloadYaml(FileType.LANG_YAML);
// Check if there is any missing entry.
checkYamlMissingEntries(FileType.LANG_YAML);
LaserGun.logger.log(Level.INFO, "All files are working correctly.");
}
private static void checkYamlMissingEntries(FileType givenFile)
{
/*
Load the file from source so we can check if the file in the plugin directory is missing any entries.
Since our file is not an actual file on the filesystem but rather a compressed file in the jar archive,
we can't directly access it via a "File file = new File();" method. To do it, we'd need to extract
the file from the archive to a temporary file, read it and then delete it.
The choice of making an InputStream instead is better because we don't risk leaving junk files
in the filesystem and we can achieve the same objective without so many resource-consuming passages.
*/
// First of all, we're gonna get the InputStream of the file from the jar archive.
InputStream is = FileUtils.class.getResourceAsStream("/" + givenFile.file.getName());
// Then, we're gonna make a Reader because we don't want to save it as a file but only load it in memory.
// Bukkit's YamlConfiguration accepts Readers so this is perfect!
Reader targetReader = new InputStreamReader(is);
// Load its YamlConfiguration.
YamlConfiguration srcYaml = YamlConfiguration.loadConfiguration(targetReader);
// Iterate each entry in the YamlConfiguration.
debugger.sendDebugMessage(Level.INFO, "Iterating src config entries for file " + givenFile.file.getName() + ".");
/* For each String which we'll name 'key' in the Set of entries of the yaml file, do...
getKeys(true) returns all the entries and all the sub-entries, which is what we need because
we want to check the whole file for missing entries.
If we wanted to only load an entry with the highest level sub-entries, we would just pass 'false'
as an argument.
Example
---- FILE ----------------
hello: 'this is a string'
myname: 4
islorenzo: 8
who: true
areu: '?'
john: false
--------------------------
Set<String> keys = srcYaml.getConfigurationSection("path").getKeys(true);
By saving our set with 'false' as an argument, and "" as the path (which means the highest level of the file),
we'd only get the 'hello' String and the 'john' boolean's value in the set.
By saving our set with 'false' as an argument, and "hello" as the path (which means the highest level of the
'hello' entry), we'd only get the 'hello' String's value and the 'hello.myname' and 'hello.islorenzo' booleans' values in the set.
By saving our set with 'true' as an argument, and "" as the path (which means the highest level of the file
with all its sub-entries), we'd get the value of all entries in the whole file ('hello', 'hello.myname', 'hello.islorenzo',
'hello.islorenzo.who', 'hello.islorenzo.areu', 'john') in the set.
By saving our set with 'true' as an argument, and "hello" as the path (which means the highest level of the
'hello' entry with all its sub-entries), we'd get the value of all entries in the 'hello' entry ('hello', 'hello.myname',
'hello.islorenzo', 'hello.islorenzo.who', 'hello.islorenzo.areu') in the set.
*/
for (String key : srcYaml.getConfigurationSection("").getKeys(true))
{
debugger.sendDebugMessage(Level.INFO, "Analyzing key '" + key + "' with default value '" + srcYaml.get(key) + "'.");
// Check if file is missing every entry.
if(!givenFile.yaml.contains(key))
{
debugger.sendDebugMessage(Level.WARNING, "Config file is missing '" + key + "' key! Proceeding to add it...");
// Add the entry to the file.
givenFile.yaml.set(key, srcYaml.get(key));
debugger.sendDebugMessage(Level.WARNING, "Added key '" + key + "' with value '" + srcYaml.get(key) + "'.");
// Save the file!
saveExistingYaml(givenFile);
}
}
debugger.sendDebugMessage(Level.INFO, "Done iterating src config entries for file " + givenFile.file.getName() + "!");
}
// Save all the info about our files location.
/*
Also initialize all files and their config, so we know where are the files when we need to save or reload them.
this is better than loading the files in the single classes that use them as if we had to reload them, we'd
need to set them again in each of the classes. Doing this instead allows us to have them all in one place.
*/
public enum FileType
{
PLUGIN_FOLDER(plugin.getDataFolder(), null),
CONFIG_YAML(new File(plugin.getDataFolder()+File.separator + "config.yml"), new YamlConfiguration()),
LANG_YAML(new File(plugin.getDataFolder()+File.separator + "lang.yml"), new YamlConfiguration());
// Constructor, so we can assign the value we set here ^ to our File.
public File file;
public YamlConfiguration yaml;
FileType(File givenFile, YamlConfiguration yamlConfig)
{
file = givenFile;
yaml = yamlConfig;
}
}
}

View File

@ -0,0 +1,20 @@
package net.mindoverflow.lasergun.utils;
public enum LocalizedMessages {
ERROR_NO_PERMISSIONS("error.no_permissions"),
ERROR_CONSOLE_ACCESS_BLOCKED("error.console_access_blocked"),
LASERGUN_NAME("info.lasergun_name"),
LASERGUN_LORE("info.lasergun_lore");
public String path;
LocalizedMessages(String path)
{
this.path = path;
}
}

View File

@ -0,0 +1,89 @@
package net.mindoverflow.lasergun.utils;
import net.mindoverflow.lasergun.LaserGun;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import java.util.logging.Level;
public class MessageUtils
{
// Initialize the Debugger instance.
private static Debugger debugger = new Debugger(MessageUtils.class.getName());
private static LaserGun plugin;
public MessageUtils(LaserGun plugin)
{
MessageUtils.plugin = plugin;
}
// Method to automatically load and send a localized message to the CommandSender.
public static void sendLocalizedMessage(CommandSender sender, LocalizedMessages messageEnum)
{
// If we actually have a sender, send it the message and color it!
if(sender != null) sender.sendMessage(getLocalizedMessage(messageEnum, true));
// If the sender is null, report it to the debugger.
else debugger.sendDebugMessage(Level.SEVERE, "Sender is null!");
}
// Method to send a colorized message to the CommandSender.
public static void sendColorizedMessage(CommandSender sender, String message)
{
// If we actually have a sender, send it the message!
if(sender != null) sender.sendMessage(colorize(message));
// If the sender is null, report it to the debugger.
else debugger.sendDebugMessage(Level.SEVERE, "Sender is null!");
}
public static String getLocalizedMessage(LocalizedMessages messageEnum, boolean applyColor)
{
/*
Load the string from the enum.
We are doing this because we don't want random strings to be passed to this method: we want it done
this way and this way only, so we don't get any error as every entry added to the enum is manually
checked before actually adding it.
*/
String path = messageEnum.path;
// Initialize the Lang file.
YamlConfiguration langFile = FileUtils.FileType.LANG_YAML.yaml;
// Initialize the message string and store the String from the lang file to it.
String localizedMessage = langFile.getString(path);
// Check if the message is null
if (localizedMessage != null)
{
// Check if we have to color the message or leave the symbols inside for further elaboration.
if(applyColor)
{
// Replace the famous '&' and '§' symbols with a ChatColor so we can color the messages!
localizedMessage = colorize(localizedMessage);
}
} else
{
// Report if the message is null.
debugger.sendDebugMessage(Level.SEVERE, "String " + path + " is null!");
}
// Return the message, whether it's colored, not colored or null (if it's null, it's the same as writing "return null").
return localizedMessage;
}
// Colorize Strings!
public static String colorize(String str)
{
/*
Since the translateAlternateColors method works with only one char and overwrites the previous one,
we are going to replace '&' with '§' and then run that method with all the '§'s.
*/
str = str.replace('&', '§');
ChatColor.translateAlternateColorCodes('§', str);
return str;
}
}

View File

@ -0,0 +1,46 @@
package net.mindoverflow.lasergun.utils;
import net.mindoverflow.lasergun.LaserGun;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import java.util.logging.Level;
public class PermissionUtils
{
// Initialize the Debugger instance.
private static Debugger debugger = new Debugger(PermissionUtils.class.getName());
private static LaserGun plugin;
public PermissionUtils(LaserGun givenPlugin) { plugin = givenPlugin; }
// Method to get the permission string from the Permissions enum.
public static boolean playerHasPermission(String username, Permissions permission)
{
debugger.sendDebugMessage(Level.INFO, "Permission: " + permission.permission + "; Player name is: " + username);
Player user = plugin.getServer().getPlayer(username);
{
if (user != null && user.hasPermission(permission.permission))
{
return true;
}
}
return false;
}
public static boolean playerHasPermission(CommandSender sender, Permissions permission)
{
debugger.sendDebugMessage(Level.INFO, "Permission: " + permission.permission + "; Player name is: " + sender.getName());
{
if(sender.hasPermission(permission.permission) || sender instanceof ConsoleCommandSender)
{
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,18 @@
package net.mindoverflow.lasergun.utils;
public enum Permissions
{
ITEM_GET("lasergun.command.getgun"),
ITEM_USE("lasergun.usegun"),
COMMAND_RELOAD("lasergun.command.reload"),
GET_UPDATES_NOTIFICATIONS("lasergun.updates"),
;
public String permission;
Permissions(String permission) { this.permission = permission; }
}

View File

@ -0,0 +1,268 @@
package net.mindoverflow.lasergun.utils.stats;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.mindoverflow.lasergun.LaserGun;
import net.mindoverflow.lasergun.utils.*;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.logging.Level;
public class UpdateChecker implements Runnable
{
public static BukkitTask task;
Debugger debugger = new Debugger(getClass().getName());
public String newVersion, updateLink;
public ArrayList<String> updateText = new ArrayList<>(), warningMessage = new ArrayList<>();
public Boolean updateWarningBoolean, isNewVersionOut = false;
public Boolean isServerUnreachable = true;
public String errorCode;
private LaserGun plugin;
public UpdateChecker(LaserGun givenPlugin)
{
plugin = givenPlugin;
}
private String servicesUrl = "https://services.mind-overflow.net/";
private String lasergunUrl = "java/plugins/lasergun/updates/";
@Override
public void run()
{
CommandSender console = plugin.getServer().getConsoleSender();
updateText.clear();
warningMessage.clear();
try
{
// Open an HTTPS Connection to the MOWS (Mind Overflow Web Services)
HttpsURLConnection connection = (HttpsURLConnection) new URL(servicesUrl).openConnection();
connection.setRequestMethod("HEAD");
// Read the response code.
int responseCode = connection.getResponseCode();
// If it's not "OK"... Stop
if (responseCode != 200)
{
setAndSendErrorCode(responseCode + "", console);
return;
}
errorCode = null;
} // Exception means the server was unreachable. Stop
catch (IOException e)
{
sendUnreachableCode(console);
isServerUnreachable = true;
return;
}
isServerUnreachable = false;
// Now, try loading the JSON file...
InputStream jsonIS;
try
{
jsonIS = new URL( servicesUrl + lasergunUrl + "update.json").openStream();
} catch (IOException e)
{
setAndSendErrorCode("null json", console);
return;
}
// And parsing it...
JsonParser jsonParser = new JsonParser();
JsonObject json = (JsonObject)jsonParser.parse(new InputStreamReader(jsonIS, StandardCharsets.UTF_8));
// Close the input stream...
try {
jsonIS.close();
} catch (IOException ignored)
{
}
// Check if the "version" String is present...
newVersion = null;
if(json.get("version") == null)
{
setAndSendErrorCode("null version", console);
return;
}
// Store it.
newVersion = json.get("version").getAsString();
// Check if versions match... And stop
if(newVersion.equalsIgnoreCase(plugin.getDescription().getVersion()))
{
isNewVersionOut = false;
return;
}
// If we are here, it means a new version is out.
isNewVersionOut = true;
// Load the update link...
updateLink = null;
if(json.get("link") == null)
{
setAndSendErrorCode("null link", console);
return;
}
updateLink = json.get("link").getAsString();
// Load all the lines from the String Array...
if(json.get("text") == null)
{
setAndSendErrorCode("null text", console);
return;
}
JsonArray updateTextArray = json.get("text").getAsJsonArray();
for(JsonElement obj : updateTextArray)
{
String relatedString = obj.getAsString();
updateText.add(relatedString);
}
// Load the warning object...
if(json.get("warning") == null)
{
setAndSendErrorCode("null warning", console);
return;
}
JsonObject warning = json.get("warning").getAsJsonObject();
// See if the warning is enabled...
if(warning.get("enabled") == null)
{
setAndSendErrorCode("null warning boolean", console);
return;
}
updateWarningBoolean = warning.get("enabled").getAsBoolean();
// Load all the lines from the String Array...
if(warning.get("text") == null)
{
setAndSendErrorCode("null warning text", console);
return;
}
JsonArray warningTextArray = warning.get("text").getAsJsonArray();
for(JsonElement obj : warningTextArray)
{
String relatedString = obj.getAsString();
warningMessage.add(relatedString);
}
// And finally send the message!
sendUpdateMessages(console);
}
public void sendUnreachableCode(CommandSender sender)
{
String pluginName = plugin.getName();
MessageUtils.sendColorizedMessage(sender, "&7-----[&3 " + pluginName + " Updater &7]-----");
MessageUtils.sendColorizedMessage(sender, "&cWarning! Updates Server is unreachable.");
MessageUtils.sendColorizedMessage(sender, "&cTry fixing connectivity problems and reload " + pluginName + " with &3/" + pluginName.toLowerCase() + " reload&c!");
}
public void setAndSendErrorCode(String code, CommandSender sender)
{
isNewVersionOut = false;
errorCode = code;
sendErrorCode(sender);
}
public void sendErrorCode(CommandSender sender)
{
String pluginName = plugin.getName();
MessageUtils.sendColorizedMessage(sender, "&7-----[&3 " + pluginName + " Updater &7]-----");
MessageUtils.sendColorizedMessage(sender, "&cWarning! Updates Server returned error code: &4" + errorCode);
MessageUtils.sendColorizedMessage(sender, "&cPlease contact the developer (" + debugger.authorName + ") immediately.");
}
public void sendUpdateMessages(CommandSender sender)
{
String pluginName = plugin.getName();
MessageUtils.sendColorizedMessage(sender, "&7-----[&3 " + pluginName + " Updater &7]-----");
MessageUtils.sendColorizedMessage(sender, "&7A new version is out: &6" + newVersion);
MessageUtils.sendColorizedMessage(sender, "&7Download: &6" + updateLink);
for(String line : updateText)
{
MessageUtils.sendColorizedMessage(sender, line);
}
if(updateWarningBoolean)
{
for(String line : warningMessage)
{
MessageUtils.sendColorizedMessage(sender, line);
}
}
}
public void playerMessage(CommandSender player)
{
plugin.getServer().getScheduler().runTaskLater(plugin, () ->
{
// Stop this in case the sender is the console: it already receives intended messages.
if(!(player instanceof Player)) return;
// Check if the updater is enabled.
if(CommonValues.updateChecker)
{
debugger.sendDebugMessage(Level.INFO, "Update Checker is enabled!");
// Check if the player has permissions to get notifications about updates.
if(PermissionUtils.playerHasPermission(player, Permissions.GET_UPDATES_NOTIFICATIONS))
{
debugger.sendDebugMessage(Level.INFO, "Player has permissions to check updates.");
// Instantiate the update checker so we can access it.
if(isNewVersionOut)
{
sendUpdateMessages(player);
}
if(isServerUnreachable)
{sendUnreachableCode(player);
}
if(errorCode != null)
{
sendErrorCode(player);
}
}
}
}, 40);
}
}

11
src/plugin.yml Normal file
View File

@ -0,0 +1,11 @@
name: LaserGun
version: alpha-BUILD_NUMBER
author: mind_overflow
main: net.mindoverflow.lasergun.LaserGun
api-version: 1.13
softdepend: [ProtocolLib]
commands:
lasergun:
description: LaserGun base command.
usage: /lasergun <args>