Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c02fb4387 | ||
|
|
2a99649e1e | ||
|
|
994bf922af | ||
|
|
36094e2bea | ||
|
|
6243b41956 | ||
|
|
32170cc089 | ||
|
|
c1a3d48944 | ||
|
|
75855826e7 | ||
|
|
d35363b10c | ||
|
|
ad1b733498 | ||
|
|
9159dfbb7d | ||
|
|
b8acd339b3 | ||
|
|
51e035eb3e | ||
|
|
2fd8e3edc3 | ||
|
|
faf20ee36e | ||
|
|
e1494808f3 | ||
|
|
05cf052204 | ||
|
|
242f05fc77 | ||
|
|
dd29fcc1dd | ||
|
|
d5013546d1 | ||
|
|
058c0837f0 | ||
|
|
e01c646562 | ||
|
|
3afca50930 | ||
|
|
94ca18e95c | ||
|
|
707eae92a8 | ||
|
|
b4a4519876 | ||
|
|
4f41b7aa6e | ||
|
|
b9267a3dfc | ||
|
|
a53c4214f0 | ||
|
|
343695e23e | ||
|
|
e17e9c8ce9 | ||
|
|
676c3a2e3d | ||
|
|
e821611744 | ||
|
|
d69c492577 | ||
|
|
eb91eefc80 | ||
|
|
f570c81366 | ||
|
|
b3f23278b1 | ||
|
|
3fa2bfa7cf | ||
|
|
582d6bef1a | ||
|
|
04c65cc59e | ||
|
|
268c4982c3 | ||
|
|
8983a0c024 | ||
|
|
1cbe901e4d | ||
|
|
4894abd1f1 | ||
|
|
1fac13247f | ||
|
|
59cfacf007 | ||
|
|
5f916fbf27 | ||
|
|
c70e254dbf | ||
|
|
9d42a05759 | ||
|
|
46f8453b5b | ||
|
|
b4b0940918 | ||
|
|
22ad7214b0 | ||
|
|
1ba693ffd5 |
No files matched your search
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 💬 Multiverse Discord Server
|
||||
url: https://discord.gg/NZtfKky
|
||||
about: Need help with using Multiverse-Core or just want to chat with the devs? Join the Multiverse Discord Server for help!
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
name: ❓ Help!
|
||||
about: Encountered a problem with Multiverse-Core? Not sure how to fix it?
|
||||
title: ''
|
||||
labels: 'type: Assistance'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Multiverse-Core help guide
|
||||
|
||||
Don't write inside the arrows as they will be hidden when you post your issue.
|
||||
|
||||
Get latest build from: http://ci.onarandombox.com/view/Multiverse/
|
||||
|
||||
If you need help other submodules of Multiverse, go to their respective git repo:
|
||||
Multiverse-Portals: https://github.com/Multiverse/Multiverse-Portals/issues
|
||||
Multiverse-NetherPortals: https://github.com/Multiverse/Multiverse-NetherPortals/issues
|
||||
Multiverse-Inventories: https://github.com/Multiverse/Multiverse-Inventories/issues
|
||||
Multiverse-SignPortals: https://github.com/Multiverse/Multiverse-SignPortals/issues
|
||||
|
||||
Or come join our Discord server to get help sooner: https://discord.gg/NZtfKky
|
||||
|
||||
If you're happy to wait (or you were sent here from Discord), read on:
|
||||
|
||||
1. Check the Usage and FAQ pages to see if it answers your queries:
|
||||
https://github.com/Multiverse/Multiverse-Core/wiki/Basics
|
||||
https://github.com/Multiverse/Multiverse-Core/wiki/FAQ
|
||||
|
||||
2. Fill out the template.
|
||||
This will help us understand what problem you've encountered and help us
|
||||
find a solution.
|
||||
|
||||
3. When linking files, do not attach them to the post!
|
||||
Copy and paste any logs into https://gist.github.com/ or other similar service.
|
||||
|
||||
4. Delete this line and all above lines before posting your issue! -->
|
||||
|
||||
### Information
|
||||
|
||||
* **Server version:** <!-- Insert output of `/version` command -->
|
||||
|
||||
* **Full output of `/mv version -b`:** <!-- Replace this with the command output's https://pastebin.com link -->
|
||||
|
||||
* **Server log:** <!-- Upload `logs/latest.log` to https://gist.github.com/ -->
|
||||
|
||||
### Help request
|
||||
|
||||
**Problem**
|
||||
<!-- What problem did you encounter? -->
|
||||
|
||||
**What I have tried**
|
||||
<!-- What have you tried so far? -->
|
||||
|
||||
**Screenshots**
|
||||
<!-- If relevant, include any screenshots here. -->
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
name: 🐛 Report a Bug
|
||||
about: Report a Multiverse-Core bug. Only use this if you're 100% sure it's something wrong with Multiverse-Core - otherwise, try "Help!".
|
||||
title: ''
|
||||
labels: 'type: Bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Multiverse-Core bug reporting guide
|
||||
|
||||
Don't put anything inside this block, as it won't be included in the issue.
|
||||
|
||||
Get latest build from: http://ci.onarandombox.com/view/Multiverse/
|
||||
|
||||
If you are having issues with other submodules of Multiverse, go to their respective git repo:
|
||||
Multiverse-Portals: https://github.com/Multiverse/Multiverse-Portals/issues
|
||||
Multiverse-NetherPortals: https://github.com/Multiverse/Multiverse-NetherPortals/issues
|
||||
Multiverse-Inventories: https://github.com/Multiverse/Multiverse-Inventories/issues
|
||||
Multiverse-SignPortals: https://github.com/Multiverse/Multiverse-SignPortals/issues
|
||||
|
||||
If you are reporting a bug, please follow the following steps:
|
||||
|
||||
1. Fill out the template in full.
|
||||
Run the commands in the console. Don't just put "latest" as a version,
|
||||
or we will ignore it.
|
||||
|
||||
2. When linking files, do not attach them to the post!
|
||||
Copy and paste any logs into https://gist.github.com/, then paste a
|
||||
link to them in the relevant parts of the template.
|
||||
**DO NOT drag files into this box!**
|
||||
|
||||
3. Make sure not to write between the arrows, as anything there will be
|
||||
hidden.
|
||||
|
||||
4. Delete this line and all above lines before posting your issue! -->
|
||||
|
||||
### Information
|
||||
|
||||
* **Server version:** <!-- Insert output of `/version` command -->
|
||||
|
||||
* **Full output of `/mv version -b`:** <!-- Replace this with the command output's https://pastebin.com link -->
|
||||
|
||||
* **Server log:** <!-- Upload `logs/latest.log` to https://gist.github.com/ -->
|
||||
|
||||
### Details
|
||||
I was **`<able / not able>`** to reproduce my issue on a freshly setup and up-to-date server with the latest version of Multiverse plugins with no other plugins and with no kinds of other server or client mods.
|
||||
|
||||
**Description**
|
||||
<!-- Replace this with a brief summary of the bug. -->
|
||||
|
||||
**Steps to reproduce**
|
||||
<!-- Replace this with exactly what you did to cause the bug. -->
|
||||
|
||||
**Expected behavior**
|
||||
<!-- Replace this with what you expected to happen. -->
|
||||
|
||||
**Screenshots**
|
||||
<!-- Replace this with screenshots, if necessary. -->
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
name: 💡 Request a Feature
|
||||
about: Suggest a feature you want to see in Multiverse-Core!
|
||||
title: ''
|
||||
labels: 'type: Suggestion'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Multiverse-Core feature request guide
|
||||
|
||||
Fill out the template. Don't write inside the arrows as they will be hidden
|
||||
when you post your issue.
|
||||
|
||||
Get latest build from: http://ci.onarandombox.com/view/Multiverse/
|
||||
|
||||
If you are look for other submodules of Multiverse, go to their respective git repo:
|
||||
Multiverse-Portals: https://github.com/Multiverse/Multiverse-Portals/issues
|
||||
Multiverse-NetherPortals: https://github.com/Multiverse/Multiverse-NetherPortals/issues
|
||||
Multiverse-Inventories: https://github.com/Multiverse/Multiverse-Inventories/issues
|
||||
Multiverse-SignPortals: https://github.com/Multiverse/Multiverse-SignPortals/issues
|
||||
|
||||
Not sure if your feature fits in Multiverse-Core? Feel free to ask on our Discord
|
||||
server: https://discord.gg/NZtfKky
|
||||
|
||||
If you have a feature suggestion for Multiverse-Core, read the following tips:
|
||||
|
||||
1. Fill out the template.
|
||||
This will help us understand what you're requesting and why you want us
|
||||
to add it.
|
||||
|
||||
2. Keep it simple.
|
||||
Make sure it's easy to understand what you're requesting. A good way is
|
||||
to keep it to one request per GitHub issue, as we can then easily track
|
||||
feature requests.
|
||||
|
||||
3. Check whether it has already been asked or added.
|
||||
You can search the issue tracker to see if your feature has already been
|
||||
requested at https://github.com/Multiverse/Multiverse-Core/issues.
|
||||
|
||||
4. Ask yourself: "Does this belong in Multiverse-Core?"
|
||||
There are lots of features that we reject because most servers won't
|
||||
need or use them. If your feature is very specific or already exists in
|
||||
another plugin, it might not be a good fit for Multiverse-Core.
|
||||
|
||||
5. Delete this line and all above lines before posting your issue! -->
|
||||
|
||||
### Feature request
|
||||
|
||||
**Feature description**
|
||||
<!-- What feature are you suggesting? -->
|
||||
|
||||
**How the feature is useful**
|
||||
<!-- How is the feature useful to players, server owners and/or developers? -->
|
||||
+1
-2
@@ -3,5 +3,4 @@ jdk:
|
||||
- oraclejdk8
|
||||
notifications:
|
||||
email: false
|
||||
before_install:
|
||||
- sed -i.bak -e 's|https://nexus.codehaus.org/snapshots/|https://oss.sonatype.org/content/repositories/codehaus-snapshots/|g' ~/.m2/settings.xml
|
||||
dist: trusty
|
||||
@@ -1,3 +0,0 @@
|
||||
machine:
|
||||
java:
|
||||
version: oraclejdk8
|
||||
@@ -3,12 +3,13 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.onarandombox.multiversecore</groupId>
|
||||
<artifactId>Multiverse-Core</artifactId>
|
||||
<version>4.1.0</version>
|
||||
<version>4.2.0</version>
|
||||
<name>Multiverse-Core</name>
|
||||
<description>World Management Plugin</description>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.build.number>UNKNOWN</project.build.number>
|
||||
<project.bitly-access-token>bitly-access-token</project.bitly-access-token>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
@@ -33,10 +34,9 @@
|
||||
<id>minebench-repo</id>
|
||||
<url>https://repo.minebench.de/</url>
|
||||
</repository>
|
||||
<!-- Has a copy of metrics R8-SNAPSHOT !-->
|
||||
<repository>
|
||||
<id>elmakers-repo</id>
|
||||
<url>http://maven.elmakers.com/repository/</url>
|
||||
<id>CodeMC</id>
|
||||
<url>https://repo.codemc.org/repository/maven-public</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
@@ -70,6 +70,17 @@
|
||||
<project.build.number>${env.BUILD_NUMBER}</project.build.number>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>bitly</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>env.BITLY_ACCESS_TOKEN</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.bitly-access-token>${env.BITLY_ACCESS_TOKEN}</project.bitly-access-token>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
@@ -91,21 +102,44 @@
|
||||
<version>1.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>replace-bitly-access-token</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>replace</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<basedir>${project.build.sourceDirectory}</basedir>
|
||||
<includes>
|
||||
<include>com/onarandombox/MultiverseCore/utils/webpaste/BitlyURLShortener.java</include>
|
||||
</includes>
|
||||
<replacements>
|
||||
<replacement>
|
||||
<token>bitly-access-token</token>
|
||||
<value>${project.bitly-access-token}</value>
|
||||
</replacement>
|
||||
</replacements>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>replace-maven-version-number</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>replace</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<basedir>${project.build.directory}/classes</basedir>
|
||||
<includes>
|
||||
<include>plugin.yml</include>
|
||||
</includes>
|
||||
<replacements>
|
||||
<replacement>
|
||||
<token>maven-version-number</token>
|
||||
<value>${project.version}-b${project.build.number}</value>
|
||||
</replacement>
|
||||
</replacements>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<file>target/classes/plugin.yml</file>
|
||||
<replacements>
|
||||
<replacement>
|
||||
<token>maven-version-number</token>
|
||||
<value>${project.version}-b${project.build.number}</value>
|
||||
</replacement>
|
||||
</replacements>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Jar Plugin -->
|
||||
<plugin>
|
||||
@@ -203,8 +237,8 @@
|
||||
<shadedPattern>com.onarandombox.buscript</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.mcstats</pattern>
|
||||
<shadedPattern>com.onarandombox.mcstats</shadedPattern>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>com.onarandombox.bstats</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.dumptruckman.minecraft.util.Logging</pattern>
|
||||
@@ -283,9 +317,9 @@
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mcstats.bukkit</groupId>
|
||||
<artifactId>metrics</artifactId>
|
||||
<version>R8-SNAPSHOT</version>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>1.7</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
|
||||
@@ -17,11 +17,9 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import buscript.Buscript;
|
||||
@@ -34,7 +32,6 @@ import com.onarandombox.MultiverseCore.api.MVPlugin;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseCoreConfig;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseMessaging;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.commands.AnchorCommand;
|
||||
import com.onarandombox.MultiverseCore.commands.CheckCommand;
|
||||
@@ -96,6 +93,7 @@ import com.onarandombox.MultiverseCore.utils.MVMessaging;
|
||||
import com.onarandombox.MultiverseCore.utils.MVPermissions;
|
||||
import com.onarandombox.MultiverseCore.utils.MVPlayerSession;
|
||||
import com.onarandombox.MultiverseCore.utils.MaterialConverter;
|
||||
import com.onarandombox.MultiverseCore.utils.metrics.MetricsConfigurator;
|
||||
import com.onarandombox.MultiverseCore.utils.SimpleBlockSafety;
|
||||
import com.onarandombox.MultiverseCore.utils.SimpleLocationManipulation;
|
||||
import com.onarandombox.MultiverseCore.utils.SimpleSafeTTeleporter;
|
||||
@@ -109,7 +107,6 @@ import org.bukkit.ChatColor;
|
||||
import org.bukkit.Difficulty;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.Configuration;
|
||||
@@ -122,7 +119,6 @@ import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.mcstats.Metrics;
|
||||
|
||||
/**
|
||||
* The implementation of the Multiverse-{@link Core}.
|
||||
@@ -340,108 +336,27 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
|
||||
// Output a little snippet to show it's enabled.
|
||||
Logging.config("Version %s (API v%s) Enabled - By %s", this.getDescription().getVersion(), PROTOCOL, getAuthors());
|
||||
|
||||
getLogger().info("Help dumptruckman keep this project alive. Become a patron! https://www.patreon.com/dumptruckman");
|
||||
getLogger().info("One time donations are also appreciated: https://www.paypal.me/dumptruckman");
|
||||
if (getMVConfig().isShowingDonateMessage()) {
|
||||
getLogger().config("Help dumptruckman keep this project alive. Become a patron! https://www.patreon.com/dumptruckman");
|
||||
getLogger().config("One time donations are also appreciated: https://www.paypal.me/dumptruckman");
|
||||
}
|
||||
}
|
||||
|
||||
private void setupMetrics() {
|
||||
MetricsConfigurator.configureMetrics(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the buscript javascript library.
|
||||
*/
|
||||
private void initializeBuscript() {
|
||||
buscript = new Buscript(this);
|
||||
// Add global variable "multiverse" to javascript environment
|
||||
buscript.setScriptVariable("multiverse", this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plotter for Environment-Values.
|
||||
*/
|
||||
private static final class EnvironmentPlotter extends Metrics.Plotter {
|
||||
private MultiverseCore core;
|
||||
private final Environment env;
|
||||
|
||||
public EnvironmentPlotter(MultiverseCore core, Environment env) {
|
||||
super(envToString(env));
|
||||
this.core = core;
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
private static String envToString(Environment env) {
|
||||
return new StringBuilder().append(env.name().toUpperCase().charAt(0))
|
||||
.append(env.name().toLowerCase().substring(1)).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getValue() {
|
||||
int count = 0;
|
||||
for (MultiverseWorld w : core.getMVWorldManager().getMVWorlds())
|
||||
if (w.getEnvironment() == env)
|
||||
count++;
|
||||
core.log(Level.FINE, String.format("Tracking %d worlds of type %s", count, env));
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plotter for Generator-Values.
|
||||
*/
|
||||
private static final class GeneratorPlotter extends Metrics.Plotter {
|
||||
private MultiverseCore core;
|
||||
private final String gen;
|
||||
|
||||
public GeneratorPlotter(MultiverseCore core, String gen) {
|
||||
super(gen);
|
||||
this.core = core;
|
||||
this.gen = gen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getValue() {
|
||||
int count = 0;
|
||||
for (MultiverseWorld w : core.getMVWorldManager().getMVWorlds())
|
||||
if (gen.equals(w.getGenerator()))
|
||||
count++;
|
||||
core.log(Level.FINE, String.format("Tracking %d worlds of type %s", count, gen));
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
private void setupMetrics() {
|
||||
try {
|
||||
Metrics m = new Metrics(this);
|
||||
|
||||
Metrics.Graph envGraph = m.createGraph("Worlds by environment");
|
||||
for (Environment env : Environment.values())
|
||||
envGraph.addPlotter(new EnvironmentPlotter(this, env));
|
||||
|
||||
Metrics.Graph loadedWorldsGraph = m.createGraph("Worlds by environment");
|
||||
loadedWorldsGraph.addPlotter(new Metrics.Plotter("Loaded worlds") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return getMVWorldManager().getMVWorlds().size();
|
||||
}
|
||||
});
|
||||
loadedWorldsGraph.addPlotter(new Metrics.Plotter("Total number of worlds") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return getMVWorldManager().getMVWorlds().size()
|
||||
+ getMVWorldManager().getUnloadedWorlds().size();
|
||||
}
|
||||
});
|
||||
|
||||
Set<String> gens = new HashSet<String>();
|
||||
for (MultiverseWorld w : this.getMVWorldManager().getMVWorlds())
|
||||
gens.add(w.getGenerator());
|
||||
gens.remove(null);
|
||||
gens.remove("null");
|
||||
Metrics.Graph genGraph = m.createGraph("Custom Generators");
|
||||
for (String gen : gens)
|
||||
genGraph.addPlotter(new GeneratorPlotter(this, gen));
|
||||
|
||||
m.start();
|
||||
log(Level.FINE, "Metrics have run!");
|
||||
} catch (Exception e) {
|
||||
log(Level.WARNING, "There was an issue while enabling metrics: " + e.getMessage());
|
||||
buscript = new Buscript(this);
|
||||
// Add global variable "multiverse" to javascript environment
|
||||
buscript.setScriptVariable("multiverse", this);
|
||||
} catch (NullPointerException e) {
|
||||
buscript = null;
|
||||
Logging.warning("Buscript failed to load! The script command will be disabled!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.onarandombox.MultiverseCore;
|
||||
|
||||
import com.dumptruckman.minecraft.util.*;
|
||||
import com.onarandombox.MultiverseCore.api.*;
|
||||
import com.onarandombox.MultiverseCore.event.MVDebugModeEvent;
|
||||
import me.main__.util.SerializationConfig.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.*;
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseCoreConfig;
|
||||
import com.onarandombox.MultiverseCore.event.MVDebugModeEvent;
|
||||
import me.main__.util.SerializationConfig.NoSuchPropertyException;
|
||||
import me.main__.util.SerializationConfig.Property;
|
||||
import me.main__.util.SerializationConfig.SerializationConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
||||
* Our configuration.
|
||||
@@ -71,6 +73,8 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
|
||||
private volatile int portalsearchradius;
|
||||
@Property
|
||||
private volatile boolean autopurge;
|
||||
@Property
|
||||
private volatile boolean idonotwanttodonate;
|
||||
|
||||
public MultiverseCoreConfiguration() {
|
||||
super();
|
||||
@@ -103,6 +107,7 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
|
||||
defaultportalsearch = false;
|
||||
portalsearchradius = 128;
|
||||
autopurge = true;
|
||||
idonotwanttodonate = false;
|
||||
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
|
||||
}
|
||||
|
||||
@@ -348,4 +353,14 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
|
||||
public void setAutoPurgeEnabled(boolean autopurge) {
|
||||
this.autopurge = autopurge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowingDonateMessage() {
|
||||
return !idonotwanttodonate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowDonateMessage(boolean showDonateMessage) {
|
||||
this.idonotwanttodonate = !showDonateMessage;
|
||||
}
|
||||
}
|
||||
@@ -213,4 +213,18 @@ public interface MultiverseCoreConfig extends ConfigurationSerializable {
|
||||
* @param autopurge True if automatic purge should be enabled.
|
||||
*/
|
||||
void setAutoPurgeEnabled(boolean autopurge);
|
||||
|
||||
/**
|
||||
* Gets whether or not the donation/patreon messages are shown.
|
||||
*
|
||||
* @return True if donation/patreon messages should be shown.
|
||||
*/
|
||||
boolean isShowingDonateMessage();
|
||||
|
||||
/**
|
||||
* Sets whether or not the donation/patreon messages are shown.
|
||||
*
|
||||
* @param idonotwanttodonate True if donation/patreon messages should be shown.
|
||||
*/
|
||||
void setShowDonateMessage(boolean idonotwanttodonate);
|
||||
}
|
||||
@@ -10,6 +10,7 @@ package com.onarandombox.MultiverseCore.commands;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameRule;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -55,21 +56,61 @@ public class GameruleCommand extends MultiverseCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
final String gameRule = args.get(0);
|
||||
final GameRule gameRule = GameRule.getByName(args.get(0));
|
||||
final String value = args.get(1);
|
||||
final World world;
|
||||
if (args.size() == 2) {
|
||||
world = p.getWorld();
|
||||
} else {
|
||||
world = Bukkit.getWorld(args.get(2));
|
||||
if (world == null) {
|
||||
sender.sendMessage(ChatColor.RED + "Failure!" + ChatColor.WHITE + " World " + ChatColor.AQUA + args.get(2)
|
||||
+ ChatColor.WHITE + " does not exist.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (world.setGameRuleValue(gameRule, value)) {
|
||||
sender.sendMessage(ChatColor.GREEN + "Success!" + ChatColor.WHITE + " Gamerule " + ChatColor.AQUA + gameRule
|
||||
+ ChatColor.WHITE + " was set to " + ChatColor.GREEN + value);
|
||||
if (gameRule == null) {
|
||||
sender.sendMessage(ChatColor.RED + "Failure! " + ChatColor.AQUA + args.get(0) + ChatColor.WHITE
|
||||
+ " is not a valid gamerule.");
|
||||
} else {
|
||||
sender.sendMessage(ChatColor.RED + "Failure!" + ChatColor.WHITE + " Gamerule " + ChatColor.AQUA + gameRule
|
||||
+ ChatColor.WHITE + " cannot be set to " + ChatColor.RED + value);
|
||||
if (gameRule.getType() == Boolean.class) {
|
||||
boolean booleanValue;
|
||||
if (value.equalsIgnoreCase("true")) {
|
||||
booleanValue = true;
|
||||
} else if (value.equalsIgnoreCase("false")) {
|
||||
booleanValue = false;
|
||||
} else {
|
||||
sender.sendMessage(getErrorMessage(gameRule.getName(), value) + "it can only be set to true or false.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!world.setGameRule(gameRule, booleanValue)) {
|
||||
sender.sendMessage(getErrorMessage(gameRule.getName(), value) + "something went wrong.");
|
||||
return;
|
||||
}
|
||||
} else if (gameRule.getType() == Integer.class) {
|
||||
try {
|
||||
if (!world.setGameRule(gameRule, Integer.parseInt(value))) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
sender.sendMessage(getErrorMessage(gameRule.getName(), value) + "it can only be set to a positive integer.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(ChatColor.RED + "Failure!" + ChatColor.WHITE + " Gamerule " + ChatColor.AQUA + gameRule.getName()
|
||||
+ ChatColor.WHITE + " isn't supported yet, please let us know about it.");
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.GREEN + "Success!" + ChatColor.WHITE + " Gamerule " + ChatColor.AQUA + gameRule.getName()
|
||||
+ ChatColor.WHITE + " was set to " + ChatColor.GREEN + value + ChatColor.WHITE + ".");
|
||||
}
|
||||
}
|
||||
|
||||
private String getErrorMessage(String gameRule, String value) {
|
||||
return ChatColor.RED + "Failure!" + ChatColor.WHITE + " Gamerule " + ChatColor.AQUA + gameRule
|
||||
+ ChatColor.WHITE + " could not be set to " + ChatColor.RED + value + ChatColor.WHITE + ", ";
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ package com.onarandombox.MultiverseCore.commands;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameRule;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -60,6 +61,11 @@ public class GamerulesCommand extends MultiverseCommand {
|
||||
world = p.getWorld();
|
||||
} else {
|
||||
world = Bukkit.getWorld(args.get(0));
|
||||
if (world == null) {
|
||||
sender.sendMessage(ChatColor.RED + "Failure!" + ChatColor.WHITE + " World " + ChatColor.AQUA + args.get(0)
|
||||
+ ChatColor.WHITE + " does not exist.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final StringBuilder gameRules = new StringBuilder();
|
||||
@@ -68,7 +74,7 @@ public class GamerulesCommand extends MultiverseCommand {
|
||||
gameRules.append(ChatColor.WHITE).append(", ");
|
||||
}
|
||||
gameRules.append(ChatColor.AQUA).append(gameRule).append(ChatColor.WHITE).append(": ");
|
||||
gameRules.append(ChatColor.GREEN).append(world.getGameRuleValue(gameRule));
|
||||
gameRules.append(ChatColor.GREEN).append(world.getGameRuleValue(GameRule.getByName(gameRule)));
|
||||
}
|
||||
sender.sendMessage("=== Gamerules for " + ChatColor.AQUA + world.getName() + ChatColor.WHITE + " ===");
|
||||
sender.sendMessage(gameRules.toString());
|
||||
|
||||
@@ -26,7 +26,7 @@ public class ListCommand extends PaginatedCoreCommand<String> {
|
||||
public ListCommand(MultiverseCore plugin) {
|
||||
super(plugin);
|
||||
this.setName("World Listing");
|
||||
this.setCommandUsage("/mv list");
|
||||
this.setCommandUsage("/mv list [page]");
|
||||
this.setArgRange(0, 2);
|
||||
this.addKey("mvlist");
|
||||
this.addKey("mvl");
|
||||
|
||||
@@ -27,6 +27,7 @@ public class ReloadCommand extends MultiverseCommand {
|
||||
this.setCommandUsage("/mv reload");
|
||||
this.setArgRange(0, 0);
|
||||
this.addKey("mvreload");
|
||||
this.addKey("mvr");
|
||||
this.addKey("mv reload");
|
||||
this.addCommandExample("/mv reload");
|
||||
this.setPermission("multiverse.core.reload", "Reloads worlds.yml and config.yml.", PermissionDefault.OP);
|
||||
|
||||
@@ -35,6 +35,10 @@ public class ScriptCommand extends MultiverseCommand {
|
||||
|
||||
@Override
|
||||
public void runCommand(CommandSender sender, List<String> args) {
|
||||
if (plugin.getScriptAPI() == null) {
|
||||
sender.sendMessage("Buscript failed to load while the server was starting. Scripts cannot be run.");
|
||||
return;
|
||||
}
|
||||
File file = new File(plugin.getScriptAPI().getScriptFolder(), args.get(0));
|
||||
if (!file.exists()) {
|
||||
sender.sendMessage("That script file does not exist in the Multiverse-Core scripts directory!");
|
||||
|
||||
@@ -30,6 +30,7 @@ public class SetSpawnCommand extends MultiverseCommand {
|
||||
this.setCommandUsage("/mv setspawn");
|
||||
this.setArgRange(0, 6);
|
||||
this.addKey("mvsetspawn");
|
||||
this.addKey("mvsets");
|
||||
this.addKey("mvss");
|
||||
this.addKey("mv set spawn");
|
||||
this.addKey("mv setspawn");
|
||||
|
||||
@@ -40,7 +40,7 @@ public class TeleportCommand extends MultiverseCommand {
|
||||
Permission menu = new Permission("multiverse.teleport.*", "Allows you to display the teleport menu.", PermissionDefault.OP);
|
||||
|
||||
this.setName("Teleport");
|
||||
this.setCommandUsage("/mv tp " + ChatColor.GOLD + "[PLAYER]" + ChatColor.GREEN + " {WORLD}");
|
||||
this.setCommandUsage("/mv tp " + ChatColor.GOLD + "[PLAYER]" + ChatColor.GREEN + " {DESTINATION}");
|
||||
this.setArgRange(1, 2);
|
||||
this.addKey("mvtp");
|
||||
this.addKey("mv tp");
|
||||
|
||||
@@ -10,12 +10,13 @@ package com.onarandombox.MultiverseCore.commands;
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.event.MVVersionEvent;
|
||||
import com.onarandombox.MultiverseCore.utils.webpaste.BitlyURLShortener;
|
||||
import com.onarandombox.MultiverseCore.utils.webpaste.PasteFailedException;
|
||||
import com.onarandombox.MultiverseCore.utils.webpaste.PasteService;
|
||||
import com.onarandombox.MultiverseCore.utils.webpaste.PasteServiceFactory;
|
||||
import com.onarandombox.MultiverseCore.utils.webpaste.PasteServiceType;
|
||||
import com.onarandombox.MultiverseCore.utils.webpaste.URLShortener;
|
||||
import com.onarandombox.MultiverseCore.utils.webpaste.URLShortenerFactory;
|
||||
import com.onarandombox.MultiverseCore.utils.webpaste.URLShortenerType;
|
||||
import com.pneumaticraft.commandhandler.CommandHandler;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
@@ -24,9 +25,12 @@ import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -35,110 +39,90 @@ import java.util.Map;
|
||||
* Dumps version info to the console.
|
||||
*/
|
||||
public class VersionCommand extends MultiverseCommand {
|
||||
private static final URLShortener SHORTENER = new BitlyURLShortener();
|
||||
private static final URLShortener SHORTENER = URLShortenerFactory.getService(URLShortenerType.BITLY);
|
||||
|
||||
public VersionCommand(MultiverseCore plugin) {
|
||||
super(plugin);
|
||||
this.setName("Multiverse Version");
|
||||
this.setCommandUsage("/mv version " + ChatColor.GOLD + "-[bh] [--include-plugin-list]");
|
||||
this.setCommandUsage("/mv version " + ChatColor.GOLD + "[-b|-h|-p] [--include-plugin-list]");
|
||||
this.setArgRange(0, 2);
|
||||
this.addKey("mv version");
|
||||
this.addKey("mvver");
|
||||
this.addKey("mvv");
|
||||
this.addKey("mvversion");
|
||||
this.setPermission("multiverse.core.version",
|
||||
"Dumps version info to the console, optionally to pastie.org with -p or pastebin.com with a -b.", PermissionDefault.TRUE);
|
||||
"Dumps version info to the console, optionally to pastebin.com with -b, to hastebin.com using -h, or to paste.gg with -p.", PermissionDefault.TRUE);
|
||||
}
|
||||
|
||||
private String getLegacyString() {
|
||||
StringBuilder legacyFile = new StringBuilder();
|
||||
legacyFile.append("[Multiverse-Core] Multiverse-Core Version: ").append(this.plugin.getDescription().getVersion()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] Bukkit Version: ").append(this.plugin.getServer().getVersion()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] Loaded Worlds: ").append(this.plugin.getMVWorldManager().getMVWorlds()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] Multiverse Plugins Loaded: ").append(this.plugin.getPluginCount()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] Economy being used: ").append(plugin.getEconomist().getEconomyName()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] Permissions Plugin: ").append(this.plugin.getMVPerms().getType()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] Dumping Config Values: (version ")
|
||||
.append(this.plugin.getMVConfig().getVersion()).append(")").append('\n');
|
||||
legacyFile.append("[Multiverse-Core] messagecooldown: ").append(plugin.getMessaging().getCooldown()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] teleportcooldown: ").append(plugin.getMVConfig().getTeleportCooldown()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] worldnameprefix: ").append(plugin.getMVConfig().getPrefixChat()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] worldnameprefixFormat: ").append(plugin.getMVConfig().getPrefixChatFormat()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] enforceaccess: ").append(plugin.getMVConfig().getEnforceAccess()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] displaypermerrors: ").append(plugin.getMVConfig().getDisplayPermErrors()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] teleportintercept: ").append(plugin.getMVConfig().getTeleportIntercept()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] firstspawnoverride: ").append(plugin.getMVConfig().getFirstSpawnOverride()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] firstspawnworld: ").append(plugin.getMVConfig().getFirstSpawnWorld()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] debug: ").append(plugin.getMVConfig().getGlobalDebug()).append('\n');
|
||||
legacyFile.append("[Multiverse-Core] Special Code: FRN002").append('\n');
|
||||
return legacyFile.toString();
|
||||
return "[Multiverse-Core] Multiverse-Core Version: " + this.plugin.getDescription().getVersion() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Bukkit Version: " + this.plugin.getServer().getVersion() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Loaded Worlds: " + this.plugin.getMVWorldManager().getMVWorlds() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Multiverse Plugins Loaded: " + this.plugin.getPluginCount() + System.lineSeparator()
|
||||
+"[Multiverse-Core] Economy being used: " + plugin.getEconomist().getEconomyName() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Permissions Plugin: " + this.plugin.getMVPerms().getType() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Dumping Config Values: (version " + this.plugin.getMVConfig().getVersion() + ")" + System.lineSeparator()
|
||||
+ "[Multiverse-Core] enforceaccess: " + plugin.getMVConfig().getEnforceAccess() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] prefixchat: " + plugin.getMVConfig().getPrefixChat() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] prefixchatformat: " + plugin.getMVConfig().getPrefixChatFormat() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] useasyncchat: " + plugin.getMVConfig().getUseAsyncChat() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] teleportintercept: " + plugin.getMVConfig().getTeleportIntercept() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] firstspawnoverride: " + plugin.getMVConfig().getFirstSpawnOverride() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] displaypermerrors: " + plugin.getMVConfig().getDisplayPermErrors() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] globaldebug: " + plugin.getMVConfig().getGlobalDebug() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] silentstart: " + plugin.getMVConfig().getSilentStart() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] messagecooldown: " + plugin.getMessaging().getCooldown() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] version: " + plugin.getMVConfig().getVersion() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] firstspawnworld: " + plugin.getMVConfig().getFirstSpawnWorld() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] teleportcooldown: " + plugin.getMVConfig().getTeleportCooldown() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] defaultportalsearch: " + plugin.getMVConfig().isUsingDefaultPortalSearch() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] portalsearchradius: " + plugin.getMVConfig().getPortalSearchRadius() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] autopurge: " + plugin.getMVConfig().isAutoPurgeEnabled() + System.lineSeparator()
|
||||
+ "[Multiverse-Core] Special Code: FRN002" + System.lineSeparator();
|
||||
}
|
||||
|
||||
private String getMarkdownString() {
|
||||
StringBuilder markdownString = new StringBuilder();
|
||||
markdownString.append("# Multiverse-Core\n");
|
||||
markdownString.append("## Overview\n");
|
||||
markdownString.append("| Name | Value |\n");
|
||||
markdownString.append("| --- | --- |\n");
|
||||
markdownString.append("| Multiverse-Core Version | `").append(this.plugin.getDescription().getVersion()).append("` |\n");
|
||||
markdownString.append("| Bukkit Version | `").append(this.plugin.getServer().getVersion()).append("` |\n");
|
||||
//markdownString.append("| Loaded Worlds | `").append(this.plugin.getMVWorldManager().getMVWorlds()).append("` |\n");
|
||||
markdownString.append("| Multiverse Plugins Loaded | `").append(this.plugin.getPluginCount()).append("` |\n");
|
||||
markdownString.append("| Economy being used | `").append(plugin.getEconomist().getEconomyName()).append("` |\n");
|
||||
markdownString.append("| Permissions Plugin | `").append(this.plugin.getMVPerms().getType()).append("` |\n");
|
||||
markdownString.append("## Parsed Config\n");
|
||||
markdownString.append("These are what Multiverse thought the in-memory values of the config were.\n\n");
|
||||
markdownString.append("| Config Key | Value |\n");
|
||||
markdownString.append("| --- | --- |\n");
|
||||
markdownString.append("| version | `").append(this.plugin.getMVConfig().getVersion()).append("` |\n");
|
||||
markdownString.append("| messagecooldown | `").append(plugin.getMessaging().getCooldown()).append("` |\n");
|
||||
markdownString.append("| teleportcooldown | `").append(plugin.getMVConfig().getTeleportCooldown()).append("` |\n");
|
||||
markdownString.append("| worldnameprefix | `").append(plugin.getMVConfig().getPrefixChat()).append("` |\n");
|
||||
markdownString.append("| worldnameprefixFormat | `").append(plugin.getMVConfig().getPrefixChatFormat()).append("` |\n");
|
||||
markdownString.append("| enforceaccess | `").append(plugin.getMVConfig().getEnforceAccess()).append("` |\n");
|
||||
markdownString.append("| displaypermerrors | `").append(plugin.getMVConfig().getDisplayPermErrors()).append("` |\n");
|
||||
markdownString.append("| teleportintercept | `").append(plugin.getMVConfig().getTeleportIntercept()).append("` |\n");
|
||||
markdownString.append("| firstspawnoverride | `").append(plugin.getMVConfig().getFirstSpawnOverride()).append("` |\n");
|
||||
markdownString.append("| firstspawnworld | `").append(plugin.getMVConfig().getFirstSpawnWorld()).append("` |\n");
|
||||
markdownString.append("| debug | `").append(plugin.getMVConfig().getGlobalDebug()).append("` |\n");
|
||||
return markdownString.toString();
|
||||
return "# Multiverse-Core" + System.lineSeparator()
|
||||
+ "## Overview" + System.lineSeparator()
|
||||
+ "| Name | Value |" + System.lineSeparator()
|
||||
+ "| --- | --- |" + System.lineSeparator()
|
||||
+ "| Multiverse-Core Version | `" + this.plugin.getDescription().getVersion() + "` |" + System.lineSeparator()
|
||||
+ "| Bukkit Version | `" + this.plugin.getServer().getVersion() + "` |" + System.lineSeparator()
|
||||
+ "| Loaded Worlds | `" + this.plugin.getMVWorldManager().getMVWorlds() + "` |" + System.lineSeparator()
|
||||
+ "| Multiverse Plugins Loaded | `" + this.plugin.getPluginCount() + "` |" + System.lineSeparator()
|
||||
+ "| Economy being used | `" + plugin.getEconomist().getEconomyName() + "` |" + System.lineSeparator()
|
||||
+ "| Permissions Plugin | `" + this.plugin.getMVPerms().getType() + "` |" + System.lineSeparator()
|
||||
+ "## Parsed Config" + System.lineSeparator()
|
||||
+ "These are what Multiverse thought the in-memory values of the config were." + System.lineSeparator() + System.lineSeparator()
|
||||
+ "| Config Key | Value |" + System.lineSeparator()
|
||||
+ "| --- | --- |" + System.lineSeparator()
|
||||
+ "| version | `" + this.plugin.getMVConfig().getVersion() + "` |" + System.lineSeparator()
|
||||
+ "| messagecooldown | `" + plugin.getMessaging().getCooldown() + "` |" + System.lineSeparator()
|
||||
+ "| teleportcooldown | `" + plugin.getMVConfig().getTeleportCooldown() + "` |" + System.lineSeparator()
|
||||
+ "| worldnameprefix | `" + plugin.getMVConfig().getPrefixChat() + "` |" + System.lineSeparator()
|
||||
+ "| worldnameprefixFormat | `" + plugin.getMVConfig().getPrefixChatFormat() + "` |" + System.lineSeparator()
|
||||
+ "| enforceaccess | `" + plugin.getMVConfig().getEnforceAccess() + "` |" + System.lineSeparator()
|
||||
+ "| displaypermerrors | `" + plugin.getMVConfig().getDisplayPermErrors() + "` |" + System.lineSeparator()
|
||||
+ "| teleportintercept | `" + plugin.getMVConfig().getTeleportIntercept() + "` |" + System.lineSeparator()
|
||||
+ "| firstspawnoverride | `" + plugin.getMVConfig().getFirstSpawnOverride() + "` |" + System.lineSeparator()
|
||||
+ "| firstspawnworld | `" + plugin.getMVConfig().getFirstSpawnWorld() + "` |" + System.lineSeparator()
|
||||
+ "| debug | `" + plugin.getMVConfig().getGlobalDebug() + "` |" + System.lineSeparator();
|
||||
}
|
||||
|
||||
private String readFile(final String filename) {
|
||||
String result;
|
||||
try {
|
||||
FileReader reader = new FileReader(filename);
|
||||
BufferedReader bufferedReader = new BufferedReader(reader);
|
||||
String line;
|
||||
result = "";
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
result += line + '\n';
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
Logging.severe("Unable to find %s. Here's the traceback: %s", filename, e.getMessage());
|
||||
e.printStackTrace();
|
||||
result = String.format("ERROR: Could not load: %s", filename);
|
||||
} catch (IOException e) {
|
||||
Logging.severe("Something bad happend when reading %s. Here's the traceback: %s", filename, e.getMessage());
|
||||
e.printStackTrace();
|
||||
result = String.format("ERROR: Could not load: %s", filename);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private void addVersionInfoToEvent(MVVersionEvent event) {
|
||||
// add the legacy version info
|
||||
event.appendVersionInfo(this.getLegacyString());
|
||||
|
||||
private Map<String, String> getVersionFiles() {
|
||||
Map<String, String> files = new HashMap<String, String>();
|
||||
// add the legacy file, but as markdown so it's readable
|
||||
event.putDetailedVersionInfo("version.md", this.getMarkdownString());
|
||||
|
||||
// Add the legacy file, but as markdown so it's readable
|
||||
files.put("version.md", this.getMarkdownString());
|
||||
|
||||
// Add the config.yml
|
||||
// add config.yml
|
||||
File configFile = new File(this.plugin.getDataFolder(), "config.yml");
|
||||
files.put(configFile.getName(), this.readFile(configFile.getAbsolutePath()));
|
||||
event.putDetailedVersionInfo("version.md", configFile);
|
||||
|
||||
// Add the config.yml
|
||||
File worldConfig = new File(this.plugin.getDataFolder(), "worlds.yml");
|
||||
files.put(worldConfig.getName(), this.readFile(worldConfig.getAbsolutePath()));
|
||||
return files;
|
||||
// add worlds.yml
|
||||
File worldsFile = new File(this.plugin.getDataFolder(), "worlds.yml");
|
||||
event.putDetailedVersionInfo("version.md", worldsFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -148,20 +132,21 @@ public class VersionCommand extends MultiverseCommand {
|
||||
sender.sendMessage("Version info dumped to console. Please check your server logs.");
|
||||
}
|
||||
|
||||
MVVersionEvent versionEvent = new MVVersionEvent(this.getLegacyString(), this.getVersionFiles());
|
||||
final Map<String, String> files = this.getVersionFiles();
|
||||
MVVersionEvent versionEvent = new MVVersionEvent();
|
||||
|
||||
this.addVersionInfoToEvent(versionEvent);
|
||||
this.plugin.getServer().getPluginManager().callEvent(versionEvent);
|
||||
|
||||
String versionInfo = versionEvent.getVersionInfo();
|
||||
|
||||
if (CommandHandler.hasFlag("--include-plugin-list", args)) {
|
||||
versionInfo = versionInfo + "\nPlugins: " + getPluginList();
|
||||
versionEvent.appendVersionInfo(System.lineSeparator() + "Plugins: " + getPluginList());
|
||||
versionEvent.putDetailedVersionInfo("plugins.txt", "Plugins: " + getPluginList());
|
||||
}
|
||||
|
||||
final String data = versionInfo;
|
||||
final String versionInfo = versionEvent.getVersionInfo();
|
||||
final Map<String, String> files = versionEvent.getDetailedVersionInfo();
|
||||
|
||||
// log to console
|
||||
String[] lines = data.split("\n");
|
||||
String[] lines = versionInfo.split(System.lineSeparator());
|
||||
for (String line : lines) {
|
||||
if (!line.isEmpty()) {
|
||||
Logging.info(line);
|
||||
@@ -175,10 +160,16 @@ public class VersionCommand extends MultiverseCommand {
|
||||
String pasteUrl;
|
||||
if (CommandHandler.hasFlag("-b", args)) {
|
||||
// private post to pastebin
|
||||
pasteUrl = postToService(PasteServiceType.PASTEBIN, true, data, files);
|
||||
pasteUrl = postToService(PasteServiceType.PASTEBIN, true, versionInfo, files);
|
||||
} else if (CommandHandler.hasFlag("-g", args)) {
|
||||
// private post to github
|
||||
pasteUrl = postToService(PasteServiceType.GITHUB, true, versionInfo, files);
|
||||
} else if (CommandHandler.hasFlag("-h", args)) {
|
||||
// private post to pastebin
|
||||
pasteUrl = postToService(PasteServiceType.HASTEBIN, true, data, files);
|
||||
// private post to hastebin
|
||||
pasteUrl = postToService(PasteServiceType.HASTEBIN, true, versionInfo, files);
|
||||
} else if (CommandHandler.hasFlag("-p", args)) {
|
||||
// private post to paste.gg
|
||||
pasteUrl = postToService(PasteServiceType.PASTEGG, true, versionInfo, files);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@@ -204,20 +195,25 @@ public class VersionCommand extends MultiverseCommand {
|
||||
* @param pasteFiles Map of filenames/contents of debug info.
|
||||
* @return URL of visible paste
|
||||
*/
|
||||
private static String postToService(PasteServiceType type, boolean isPrivate, String pasteData,
|
||||
Map<String, String> pasteFiles) {
|
||||
private static String postToService(PasteServiceType type, boolean isPrivate, String pasteData, Map<String, String> pasteFiles) {
|
||||
PasteService ps = PasteServiceFactory.getService(type, isPrivate);
|
||||
|
||||
try {
|
||||
String result;
|
||||
if (ps.supportsMultiFile()) {
|
||||
result = ps.postData(ps.encodeData(pasteFiles), ps.getPostURL());
|
||||
result = ps.postData(pasteFiles);
|
||||
} else {
|
||||
result = ps.postData(ps.encodeData(pasteData), ps.getPostURL());
|
||||
result = ps.postData(pasteData);
|
||||
}
|
||||
return SHORTENER.shorten(result);
|
||||
|
||||
if (SHORTENER != null) return SHORTENER.shorten(result);
|
||||
return result;
|
||||
} catch (PasteFailedException e) {
|
||||
System.out.print(e);
|
||||
return "Error posting to service";
|
||||
e.printStackTrace();
|
||||
return "Error posting to service.";
|
||||
} catch (NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
return "That service isn't supported yet.";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
package com.onarandombox.MultiverseCore.event;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -13,9 +21,9 @@ public class MVVersionEvent extends Event {
|
||||
private final StringBuilder versionInfoBuilder;
|
||||
private final Map<String, String> detailedVersionInfo;
|
||||
|
||||
public MVVersionEvent(String legacyVersionInfo, Map<String, String> files) {
|
||||
this.versionInfoBuilder = new StringBuilder(legacyVersionInfo);
|
||||
this.detailedVersionInfo = files;
|
||||
public MVVersionEvent() {
|
||||
versionInfoBuilder = new StringBuilder();
|
||||
detailedVersionInfo = new HashMap<>();
|
||||
}
|
||||
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
@@ -49,14 +57,14 @@ public class MVVersionEvent extends Event {
|
||||
*
|
||||
* This information is used for advanced paste services that would prefer
|
||||
* to get the information as several files. Examples include config.yml or
|
||||
* portals.yml.
|
||||
* portals.yml. Note that the map returned is immutable.
|
||||
*
|
||||
* The keys are filenames, the values are the contents of the files.
|
||||
*
|
||||
* @return The key value mapping of files and the contents of those files.
|
||||
* @return The immutable key value mapping of files and the contents of those files.
|
||||
*/
|
||||
public Map<String, String> getDetailedVersionInfo() {
|
||||
return this.detailedVersionInfo;
|
||||
return Collections.unmodifiableMap(this.detailedVersionInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,4 +74,46 @@ public class MVVersionEvent extends Event {
|
||||
public void appendVersionInfo(String moreVersionInfo) {
|
||||
this.versionInfoBuilder.append(moreVersionInfo);
|
||||
}
|
||||
|
||||
private String readFile(final String filename) {
|
||||
StringBuilder result;
|
||||
|
||||
try {
|
||||
FileReader reader = new FileReader(filename);
|
||||
BufferedReader bufferedReader = new BufferedReader(reader);
|
||||
String line;
|
||||
result = new StringBuilder();
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
result.append(line).append("\n");
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
Logging.severe("Unable to find %s. Here's the traceback: %s", filename, e.getMessage());
|
||||
e.printStackTrace();
|
||||
result = new StringBuilder(String.format("ERROR: Could not load: %s", filename));
|
||||
} catch (IOException e) {
|
||||
Logging.severe("Something bad happend when reading %s. Here's the traceback: %s", filename, e.getMessage());
|
||||
e.printStackTrace();
|
||||
result = new StringBuilder(String.format("ERROR: Could not load: %s", filename));
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a file to to the detailed version-info currently saved in this event.
|
||||
* @param fileName The name of the file.
|
||||
* @param contents The contents of the file.
|
||||
*/
|
||||
public void putDetailedVersionInfo(String fileName, String contents) {
|
||||
this.detailedVersionInfo.put(fileName, contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a file to to the detailed version-info currently saved in this event.
|
||||
* @param filename The name of the file.
|
||||
* @param file The file.
|
||||
*/
|
||||
public void putDetailedVersionInfo(String filename, File file) {
|
||||
this.putDetailedVersionInfo(filename, readFile(file.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,9 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
@@ -72,14 +74,27 @@ public class FileUtils {
|
||||
* @param target Target-File
|
||||
* @param log A logger that logs the operation
|
||||
*
|
||||
* @return if it had success
|
||||
* @return true if it had success
|
||||
*/
|
||||
public static boolean copyFolder(File source, File target, Logger log) {
|
||||
return copyFolder(source, target, null, log);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to copy the world-folder.
|
||||
* @param source Source-File
|
||||
* @param target Target-File
|
||||
* @param excludeFiles files to ignore and not copy over to Target-File
|
||||
* @param log A logger that logs the operation
|
||||
*
|
||||
* @return true if it had success
|
||||
*/
|
||||
public static boolean copyFolder(File source, File target, List<String> excludeFiles, Logger log) {
|
||||
Path sourceDir = source.toPath();
|
||||
Path targetDir = target.toPath();
|
||||
|
||||
try {
|
||||
Files.walkFileTree(sourceDir, new CopyDirFileVisitor(sourceDir, targetDir));
|
||||
Files.walkFileTree(sourceDir, new CopyDirFileVisitor(sourceDir, targetDir, excludeFiles));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
log.log(Level.WARNING, "Unable to copy directory", e);
|
||||
@@ -91,10 +106,12 @@ public class FileUtils {
|
||||
|
||||
private final Path sourceDir;
|
||||
private final Path targetDir;
|
||||
private final List<String> excludeFiles;
|
||||
|
||||
private CopyDirFileVisitor(Path sourceDir, Path targetDir) {
|
||||
private CopyDirFileVisitor(Path sourceDir, Path targetDir, List<String> excludeFiles) {
|
||||
this.sourceDir = sourceDir;
|
||||
this.targetDir = targetDir;
|
||||
this.excludeFiles = excludeFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,9 +125,13 @@ public class FileUtils {
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
// Pass files that are set to ignore
|
||||
if (excludeFiles != null && excludeFiles.contains(file.getFileName().toString()))
|
||||
return FileVisitResult.CONTINUE;
|
||||
// Copy the files
|
||||
Path targetFile = targetDir.resolve(sourceDir.relativize(file));
|
||||
Files.copy(file, targetFile, COPY_ATTRIBUTES);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import com.onarandombox.MultiverseCore.api.LocationManipulation;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -52,7 +53,7 @@ public class SimpleLocationManipulation implements LocationManipulation {
|
||||
if (location == null) {
|
||||
return "";
|
||||
}
|
||||
return String.format("%s:%.2f,%.2f,%.2f:%.2f:%.2f", location.getWorld().getName(),
|
||||
return String.format(Locale.ENGLISH, "%s:%.2f,%.2f,%.2f:%.2f:%.2f", location.getWorld().getName(),
|
||||
location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
}
|
||||
|
||||
|
||||
@@ -43,15 +43,19 @@ import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Public facing API to add/remove Multiverse worlds.
|
||||
*/
|
||||
public class WorldManager implements MVWorldManager {
|
||||
private final MultiverseCore plugin;
|
||||
private final Pattern worldNamePattern = Pattern.compile("[a-zA-Z0-9/._-]+");
|
||||
private final WorldPurger worldPurger;
|
||||
private final Map<String, MultiverseWorld> worlds;
|
||||
private Map<String, WorldProperties> worldsFromTheConfig;
|
||||
@@ -125,8 +129,14 @@ public class WorldManager implements MVWorldManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for valid world name
|
||||
if (!(isValidWorldName(oldName) && isValidWorldName(newName))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final File oldWorldFile = new File(this.plugin.getServer().getWorldContainer(), oldName);
|
||||
final File newWorldFile = new File(this.plugin.getServer().getWorldContainer(), newName);
|
||||
final List<String> ignoreFiles = new ArrayList<>(Arrays.asList("session.lock", "uid.dat"));
|
||||
|
||||
// Make sure the new world doesn't exist outside of multiverse.
|
||||
if (newWorldFile.exists()) {
|
||||
@@ -177,32 +187,40 @@ public class WorldManager implements MVWorldManager {
|
||||
oldWorld.getCBWorld().save();
|
||||
}
|
||||
Logging.config("Copying files for world '%s'", oldName);
|
||||
if (!FileUtils.copyFolder(oldWorldFile, newWorldFile, Logging.getLogger())) {
|
||||
if (!FileUtils.copyFolder(oldWorldFile, newWorldFile, ignoreFiles, Logging.getLogger())) {
|
||||
Logging.warning("Failed to copy files for world '%s', see the log info", newName);
|
||||
return false;
|
||||
}
|
||||
if (oldWorld != null && wasAutoSave) {
|
||||
oldWorld.getCBWorld().setAutoSave(true);
|
||||
}
|
||||
|
||||
if (newWorldFile.exists()) {
|
||||
Logging.fine("Succeeded at copying files");
|
||||
|
||||
File uidFile = new File(newWorldFile, "uid.dat");
|
||||
if (uidFile.exists() && !uidFile.delete()) {
|
||||
Logging.warning("Failed to delete unique ID file for world '%s'", newName);
|
||||
// initialize new properties with old ones
|
||||
WorldProperties newProps = new WorldProperties();
|
||||
newProps.copyValues(this.worldsFromTheConfig.get(oldName));
|
||||
// don't keep the alias the same -- that would be useless
|
||||
newProps.setAlias("");
|
||||
// store the new properties in worlds config map
|
||||
this.worldsFromTheConfig.put(newName, newProps);
|
||||
|
||||
// save the worlds config to disk (worlds.yml)
|
||||
if (!saveWorldsConfig()) {
|
||||
this.plugin.log(Level.SEVERE, "Failed to save worlds.yml");
|
||||
return false;
|
||||
}
|
||||
|
||||
// actually load the world
|
||||
if (doLoad(newName)) {
|
||||
this.plugin.log(Level.FINE, "Succeeded at loading cloned world '" + newName + "'");
|
||||
return true;
|
||||
}
|
||||
this.plugin.log(Level.SEVERE, "Failed to load the cloned world '" + newName + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newWorldFile.exists()) {
|
||||
Logging.fine("Succeeded at copying files");
|
||||
if (this.addWorld(newName, environment, seedString, worldType, generateStructures, generator, useSpawnAdjust)) {
|
||||
// getMVWorld() doesn't actually return an MVWorld
|
||||
Logging.fine("Succeeded at importing world");
|
||||
MVWorld newWorld = (MVWorld) this.getMVWorld(newName);
|
||||
newWorld.copyValues(this.worldsFromTheConfig.get(oldName));
|
||||
// don't keep the alias the same -- that would be useless
|
||||
newWorld.setAlias(null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Logging.warning("Failed to copy files for world '%s', see the log info", newName);
|
||||
return false;
|
||||
}
|
||||
@@ -225,6 +243,11 @@ public class WorldManager implements MVWorldManager {
|
||||
if (name.equalsIgnoreCase("plugins") || name.equalsIgnoreCase("logs")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isValidWorldName(name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Long seed = null;
|
||||
WorldCreator c = new WorldCreator(name);
|
||||
if (seedString != null && seedString.length() > 0) {
|
||||
@@ -407,6 +430,21 @@ public class WorldManager implements MVWorldManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the world name is allowed
|
||||
*
|
||||
* @param name Name of the world
|
||||
* @return True if the world world name is valid based on regex
|
||||
*/
|
||||
private boolean isValidWorldName(String name) {
|
||||
if (!worldNamePattern.matcher(name).matches()) {
|
||||
Logging.warning("Invalid world name '" + name + "'");
|
||||
Logging.warning("World name should not contain spaces or special characters!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void brokenWorld(String name) {
|
||||
this.plugin.log(Level.SEVERE, "The world '" + name + "' could NOT be loaded because it contains errors and is probably corrupt!");
|
||||
this.plugin.log(Level.SEVERE, "Try using Minecraft Region Fixer to repair your world! '" + name + "'");
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.onarandombox.MultiverseCore.utils.metrics;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.World;
|
||||
|
||||
public class MetricsConfigurator {
|
||||
|
||||
private static final int PLUGIN_ID = 7765;
|
||||
private static final String NO_GENERATOR_NAME = "N/A";
|
||||
|
||||
public static void configureMetrics(MultiverseCore plugin) {
|
||||
MetricsConfigurator configurator = new MetricsConfigurator(plugin);
|
||||
configurator.initMetrics();
|
||||
}
|
||||
|
||||
private final MultiverseCore plugin;
|
||||
private final Metrics metrics;
|
||||
|
||||
private MetricsConfigurator(MultiverseCore plugin) {
|
||||
this.plugin = plugin;
|
||||
this.metrics = new Metrics(plugin, PLUGIN_ID);
|
||||
}
|
||||
|
||||
private MVWorldManager getWorldManager() {
|
||||
return plugin.getMVWorldManager();
|
||||
}
|
||||
|
||||
private Collection<MultiverseWorld> getMVWorlds() {
|
||||
return getWorldManager().getMVWorlds();
|
||||
}
|
||||
|
||||
private void initMetrics() {
|
||||
try {
|
||||
addCustomGeneratorsMetric();
|
||||
addEnvironmentsMetric();
|
||||
addWorldCountMetric();
|
||||
|
||||
Logging.fine("Metrics enabled.");
|
||||
} catch (Exception e) {
|
||||
Logging.warning("There was an issue while enabling metrics:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void addCustomGeneratorsMetric() {
|
||||
addAdvancedPieMetric("custom_generators", map -> {
|
||||
for (MultiverseWorld w : getMVWorlds()) {
|
||||
MetricsHelper.incrementCount(map, getGeneratorName(w));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String getGeneratorName(MultiverseWorld world) {
|
||||
String gen = world.getGenerator();
|
||||
return (gen != null && !gen.equalsIgnoreCase("null")) ? gen.split(":")[0] : NO_GENERATOR_NAME;
|
||||
}
|
||||
|
||||
private void addEnvironmentsMetric() {
|
||||
addAdvancedPieMetric("environments", map -> {
|
||||
for (MultiverseWorld w : getMVWorlds()) {
|
||||
MetricsHelper.incrementCount(map, titleCaseEnv(w.getEnvironment()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String titleCaseEnv(World.Environment env) {
|
||||
String envName = env.name().replaceAll("_+", " ");
|
||||
return WordUtils.capitalizeFully(envName);
|
||||
}
|
||||
|
||||
private void addWorldCountMetric() {
|
||||
addMultiLineMetric("world_count", map -> {
|
||||
int loadedWorldsCount = getMVWorlds().size();
|
||||
map.put("Loaded worlds", loadedWorldsCount);
|
||||
map.put("Total number of worlds", loadedWorldsCount + getWorldManager().getUnloadedWorlds().size());
|
||||
});
|
||||
}
|
||||
|
||||
private void addAdvancedPieMetric(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
metrics.addCustomChart(MetricsHelper.createAdvancedPieChart(chartId, metricsFunc));
|
||||
}
|
||||
|
||||
private void addMultiLineMetric(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
metrics.addCustomChart(MetricsHelper.createMultiLineChart(chartId, metricsFunc));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.onarandombox.MultiverseCore.utils.metrics;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.bstats.bukkit.Metrics;
|
||||
|
||||
enum MetricsHelper {
|
||||
;
|
||||
|
||||
/**
|
||||
* Adds one to the value in the given map with the given key. If the key does not exist in the map, it will be added with a value of 1.
|
||||
*/
|
||||
static void incrementCount(Map<String, Integer> map, String key) {
|
||||
Integer count = map.getOrDefault(key, 0);
|
||||
map.put(key, count + 1);
|
||||
}
|
||||
|
||||
static Metrics.AdvancedPie createAdvancedPieChart(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
metricsFunc.accept(map);
|
||||
return new Metrics.AdvancedPie(chartId, () -> map);
|
||||
}
|
||||
|
||||
static Metrics.MultiLineChart createMultiLineChart(String chartId, Consumer<Map<String, Integer>> metricsFunc) {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
metricsFunc.accept(map);
|
||||
return new Metrics.MultiLineChart(chartId, () -> map);
|
||||
}
|
||||
|
||||
}
|
||||
+36
-14
@@ -1,19 +1,43 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An {@link URLShortener} using {@code bit.ly}.
|
||||
* A {@link URLShortener} using {@code bit.ly}. Requires an access token.
|
||||
*/
|
||||
public class BitlyURLShortener extends HttpAPIClient implements URLShortener {
|
||||
private static final String GENERIC_BITLY_REQUEST_FORMAT = "https://api-ssl.bitly.com/v3/shorten?format=txt&apiKey=%s&login=%s&longUrl=%s";
|
||||
class BitlyURLShortener extends URLShortener {
|
||||
private static final String ACCESS_TOKEN = "Bearer bitly-access-token";
|
||||
private static final String BITLY_POST_REQUEST = "https://api-ssl.bitly.com/v4/shorten";
|
||||
|
||||
// I think it's no problem that these are public
|
||||
private static final String USERNAME = "multiverse2";
|
||||
private static final String API_KEY = "R_9dbff4862a3bc0c4218a7d78cc10d0e0";
|
||||
BitlyURLShortener() {
|
||||
super(BITLY_POST_REQUEST, ACCESS_TOKEN);
|
||||
if (ACCESS_TOKEN.endsWith("access-token")) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public BitlyURLShortener() {
|
||||
super(String.format(GENERIC_BITLY_REQUEST_FORMAT, API_KEY, USERNAME, "%s"));
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
String encodeData(String data) {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("domain", "j.mp");
|
||||
json.put("long_url", data);
|
||||
return json.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
String encodeData(Map<String, String> data) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -22,13 +46,11 @@ public class BitlyURLShortener extends HttpAPIClient implements URLShortener {
|
||||
@Override
|
||||
public String shorten(String longUrl) {
|
||||
try {
|
||||
String result = this.exec(longUrl);
|
||||
if (!result.startsWith("http://j.mp/")) // ... then it's failed :/
|
||||
throw new IOException(result);
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
String stringJSON = this.exec(encodeData(longUrl), ContentType.JSON);
|
||||
return (String) ((JSONObject) new JSONParser().parse(stringJSON)).get("link");
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
return longUrl; // sorry ...
|
||||
return longUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Pastes to {@code gist.github.com}. Requires an access token with the {@code gist} scope.
|
||||
*/
|
||||
class GitHubPasteService extends PasteService {
|
||||
private final boolean isPrivate;
|
||||
// this access token must have the "gist" scope
|
||||
private static final String ACCESS_TOKEN = "token github-access-token";
|
||||
private static final String GITHUB_POST_REQUEST = "https://api.github.com/gists";
|
||||
|
||||
GitHubPasteService(boolean isPrivate) {
|
||||
super(GITHUB_POST_REQUEST, ACCESS_TOKEN);
|
||||
this.isPrivate = isPrivate;
|
||||
if (ACCESS_TOKEN.endsWith("access-token")) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
String encodeData(String data) {
|
||||
Map<String, String> mapData = new HashMap<String, String>();
|
||||
mapData.put("multiverse.txt", data);
|
||||
return this.encodeData(mapData);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
String encodeData(Map<String, String> files) {
|
||||
JSONObject root = new JSONObject();
|
||||
root.put("description", "Multiverse-Core Debug Info");
|
||||
root.put("public", !this.isPrivate);
|
||||
JSONObject fileList = new JSONObject();
|
||||
for (Map.Entry<String, String> entry : files.entrySet()) {
|
||||
JSONObject fileObject = new JSONObject();
|
||||
fileObject.put("content", entry.getValue());
|
||||
fileList.put(entry.getKey(), fileObject);
|
||||
}
|
||||
|
||||
root.put("files", fileList);
|
||||
return root.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String postData(String data) throws PasteFailedException {
|
||||
try {
|
||||
String stringJSON = this.exec(encodeData(data), ContentType.JSON);
|
||||
return (String) ((JSONObject) new JSONParser().parse(stringJSON)).get("html_url");
|
||||
} catch (IOException | ParseException e) {
|
||||
throw new PasteFailedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String postData(Map<String, String> data) throws PasteFailedException {
|
||||
try {
|
||||
String stringJSON = this.exec(encodeData(data), ContentType.JSON);
|
||||
return (String) ((JSONObject) new JSONParser().parse(stringJSON)).get("html_url");
|
||||
} catch (IOException | ParseException e) {
|
||||
throw new PasteFailedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsMultiFile() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class GithubPasteService implements PasteService {
|
||||
|
||||
private final boolean isPrivate;
|
||||
|
||||
public GithubPasteService(boolean isPrivate) {
|
||||
this.isPrivate = isPrivate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodeData(String data) {
|
||||
Map<String, String> mapData = new HashMap<String, String>();
|
||||
mapData.put("multiverse.txt", data);
|
||||
return this.encodeData(mapData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodeData(Map<String, String> files) {
|
||||
JsonObject root = new JsonObject();
|
||||
root.add("description", new JsonPrimitive("Multiverse-Core Debug Info"));
|
||||
root.add("public", new JsonPrimitive(!this.isPrivate));
|
||||
JsonObject fileList = new JsonObject();
|
||||
for (Map.Entry<String, String> entry : files.entrySet())
|
||||
{
|
||||
JsonObject fileObject = new JsonObject();
|
||||
fileObject.add("content", new JsonPrimitive(entry.getValue()));
|
||||
fileList.add(entry.getKey(), fileObject);
|
||||
}
|
||||
root.add("files", fileList);
|
||||
return root.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getPostURL() {
|
||||
try {
|
||||
return new URL("https://api.github.com/gists");
|
||||
//return new URL("http://jsonplaceholder.typicode.com/posts");
|
||||
} catch (MalformedURLException e) {
|
||||
return null; // should never hit here
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String postData(String encodedData, URL url) throws PasteFailedException {
|
||||
OutputStreamWriter wr = null;
|
||||
BufferedReader rd = null;
|
||||
try {
|
||||
URLConnection conn = url.openConnection();
|
||||
conn.setDoOutput(true);
|
||||
wr = new OutputStreamWriter(conn.getOutputStream());
|
||||
wr.write(encodedData);
|
||||
wr.flush();
|
||||
|
||||
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String line;
|
||||
String pastieUrl = "";
|
||||
//Pattern pastiePattern = this.getURLMatchingPattern();
|
||||
StringBuilder responseString = new StringBuilder();
|
||||
|
||||
while ((line = rd.readLine()) != null) {
|
||||
responseString.append(line);
|
||||
}
|
||||
return new JsonParser().parse(responseString.toString()).getAsJsonObject().get("html_url").getAsString();
|
||||
} catch (Exception e) {
|
||||
throw new PasteFailedException(e);
|
||||
} finally {
|
||||
if (wr != null) {
|
||||
try {
|
||||
wr.close();
|
||||
} catch (IOException ignore) { }
|
||||
}
|
||||
if (rd != null) {
|
||||
try {
|
||||
rd.close();
|
||||
} catch (IOException ignore) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsMultiFile() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+40
-52
@@ -1,79 +1,67 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Pastes to {@code hastebin.com}.
|
||||
*/
|
||||
public class HastebinPasteService implements PasteService {
|
||||
class HastebinPasteService extends PasteService {
|
||||
private static final String HASTEBIN_POST_REQUEST = "https://hastebin.com/documents";
|
||||
|
||||
HastebinPasteService() {
|
||||
super(HASTEBIN_POST_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String encodeData(String data) {
|
||||
String encodeData(String data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String encodeData(Map<String, String> data) {
|
||||
String encodeData(Map<String, String> data) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public URL getPostURL() {
|
||||
public String postData(String data) throws PasteFailedException {
|
||||
try {
|
||||
return new URL("https://hastebin.com/documents");
|
||||
} catch (MalformedURLException e) {
|
||||
return null; // should never hit here
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String postData(String encodedData, URL url) throws PasteFailedException {
|
||||
OutputStreamWriter wr = null;
|
||||
BufferedReader rd = null;
|
||||
try {
|
||||
URLConnection conn = url.openConnection();
|
||||
conn.setDoOutput(true);
|
||||
|
||||
wr = new OutputStreamWriter(conn.getOutputStream());
|
||||
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
|
||||
wr.write(encodedData);
|
||||
wr.flush();
|
||||
|
||||
String line;
|
||||
StringBuilder responseString = new StringBuilder();
|
||||
while ((line = rd.readLine()) != null) {
|
||||
responseString.append(line);
|
||||
}
|
||||
String key = new JsonParser().parse(responseString.toString()).getAsJsonObject().get("key").getAsString();
|
||||
|
||||
return "https://hastebin.com/" + key;
|
||||
} catch (Exception e) {
|
||||
String stringJSON = this.exec(encodeData(data), ContentType.PLAINTEXT);
|
||||
return "https://hastebin.com/" + ((JSONObject) new JSONParser().parse(stringJSON)).get("key");
|
||||
} catch (IOException | ParseException e) {
|
||||
throw new PasteFailedException(e);
|
||||
} finally {
|
||||
if (wr != null) {
|
||||
try {
|
||||
wr.close();
|
||||
} catch (IOException ignore) { }
|
||||
}
|
||||
if (rd != null) {
|
||||
try {
|
||||
rd.close();
|
||||
} catch (IOException ignore) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String postData(Map<String, String> data) throws PasteFailedException {
|
||||
try {
|
||||
String stringJSON = this.exec(encodeData(data), ContentType.PLAINTEXT);
|
||||
return "https://hastebin.com/" + ((JSONObject) new JSONParser().parse(stringJSON)).get("key");
|
||||
} catch (IOException | ParseException e) {
|
||||
throw new PasteFailedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsMultiFile() {
|
||||
return false;
|
||||
|
||||
@@ -1,50 +1,129 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* HTTP API-client.
|
||||
*/
|
||||
public abstract class HttpAPIClient {
|
||||
abstract class HttpAPIClient {
|
||||
/**
|
||||
* The URL for this API-request.
|
||||
* The URL for this API-request, and if necessary, the access token.
|
||||
* If an access token is not necessary, it should be set to null.
|
||||
*/
|
||||
protected final String urlFormat;
|
||||
private final String url;
|
||||
private final String accessToken;
|
||||
|
||||
public HttpAPIClient(String urlFormat) {
|
||||
this.urlFormat = urlFormat;
|
||||
/**
|
||||
* Types of data that can be sent.
|
||||
*/
|
||||
enum ContentType {
|
||||
JSON,
|
||||
PLAINTEXT,
|
||||
URLENCODED
|
||||
}
|
||||
|
||||
HttpAPIClient(String url) {
|
||||
this(url, null);
|
||||
}
|
||||
|
||||
HttpAPIClient(String url, String accessToken) {
|
||||
this.url = url;
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP Content-Type header that corresponds with each ContentType.
|
||||
* @param type The type of data.
|
||||
* @return The HTTP Content-Type header that corresponds with the type of data.
|
||||
*/
|
||||
private String getContentHeader(ContentType type) {
|
||||
switch (type) {
|
||||
case JSON:
|
||||
return "application/json; charset=utf-8";
|
||||
case PLAINTEXT:
|
||||
return "text/plain; charset=utf-8";
|
||||
case URLENCODED:
|
||||
return "application/x-www-form-urlencoded; charset=utf-8";
|
||||
default:
|
||||
throw new IllegalArgumentException("Unexpected value: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given String data into a format suitable for transmission in an HTTP request.
|
||||
*
|
||||
* @param data The raw data to encode.
|
||||
* @return A URL-encoded string.
|
||||
*/
|
||||
abstract String encodeData(String data);
|
||||
|
||||
/**
|
||||
* Encode the given Map data into a format suitable for transmission in an HTTP request.
|
||||
*
|
||||
* @param data The raw data to encode.
|
||||
* @return A URL-encoded string.
|
||||
*/
|
||||
abstract String encodeData(Map<String, String> data);
|
||||
|
||||
/**
|
||||
* Executes this API-Request.
|
||||
* @param args Format-args.
|
||||
* @param payload The data that will be sent.
|
||||
* @param type The type of data that will be sent.
|
||||
* @return The result (as text).
|
||||
* @throws IOException When the I/O-operation failed.
|
||||
*/
|
||||
protected final String exec(Object... args) throws IOException {
|
||||
final String exec(String payload, ContentType type) throws IOException {
|
||||
BufferedReader rd = null;
|
||||
OutputStreamWriter wr = null;
|
||||
|
||||
URLConnection conn = new URL(String.format(this.urlFormat, args)).openConnection();
|
||||
conn.connect();
|
||||
StringBuilder ret = new StringBuilder();
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
while (!reader.ready()); // wait until reader is ready, may not be necessary, SUPPRESS CHECKSTYLE: EmptyStatement
|
||||
HttpsURLConnection conn = (HttpsURLConnection) new URL(this.url).openConnection();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setDoOutput(true);
|
||||
|
||||
while (reader.ready()) {
|
||||
ret.append(reader.readLine()).append('\n');
|
||||
// we can receive anything!
|
||||
conn.addRequestProperty("Accept", "*/*");
|
||||
// set a dummy User-Agent
|
||||
conn.addRequestProperty("User-Agent", "placeholder");
|
||||
// this isn't required, but is technically correct
|
||||
conn.addRequestProperty("Content-Type", getContentHeader(type));
|
||||
// only some API requests require an access token
|
||||
if (this.accessToken != null) {
|
||||
conn.addRequestProperty("Authorization", this.accessToken);
|
||||
}
|
||||
|
||||
wr = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8.newEncoder());
|
||||
wr.write(payload);
|
||||
wr.flush();
|
||||
|
||||
String line;
|
||||
StringBuilder responseString = new StringBuilder();
|
||||
// this has to be initialized AFTER the data has been flushed!
|
||||
rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
|
||||
|
||||
while ((line = rd.readLine()) != null) {
|
||||
responseString.append(line);
|
||||
}
|
||||
|
||||
return responseString.toString();
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
if (wr != null) {
|
||||
try {
|
||||
reader.close();
|
||||
wr.close();
|
||||
} catch (IOException ignore) { }
|
||||
}
|
||||
if (rd != null) {
|
||||
try {
|
||||
rd.close();
|
||||
} catch (IOException ignore) { }
|
||||
}
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
/**
|
||||
* Thrown when pasting failed.
|
||||
* Thrown when pasting fails.
|
||||
*/
|
||||
public class PasteFailedException extends Exception {
|
||||
public PasteFailedException() {
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Pastes to {@code paste.gg}.
|
||||
*/
|
||||
class PasteGGPasteService extends PasteService {
|
||||
private final boolean isPrivate;
|
||||
private static final String PASTEGG_POST_REQUEST = "https://api.paste.gg/v1/pastes";
|
||||
|
||||
PasteGGPasteService(boolean isPrivate) {
|
||||
super(PASTEGG_POST_REQUEST);
|
||||
this.isPrivate = isPrivate;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
String encodeData(String data) {
|
||||
Map<String, String> mapData = new HashMap<String, String>();
|
||||
mapData.put("multiverse.txt", data);
|
||||
return this.encodeData(mapData);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
String encodeData(Map<String, String> files) {
|
||||
JSONObject root = new JSONObject();
|
||||
root.put("name", "Multiverse-Core Debug Info");
|
||||
root.put("visibility", this.isPrivate ? "unlisted" : "public");
|
||||
JSONArray fileList = new JSONArray();
|
||||
for (Map.Entry<String, String> entry : files.entrySet()) {
|
||||
JSONObject fileObject = new JSONObject();
|
||||
JSONObject contentObject = new JSONObject();
|
||||
fileObject.put("name", entry.getKey());
|
||||
fileObject.put("content", contentObject);
|
||||
contentObject.put("format", "text");
|
||||
contentObject.put("value", entry.getValue());
|
||||
fileList.add(fileObject);
|
||||
}
|
||||
|
||||
root.put("files", fileList);
|
||||
return root.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String postData(String data) throws PasteFailedException {
|
||||
try {
|
||||
String stringJSON = this.exec(encodeData(data), ContentType.JSON);
|
||||
return (String) ((JSONObject) ((JSONObject) new JSONParser().parse(stringJSON)).get("result")).get("id");
|
||||
} catch (IOException | ParseException e) {
|
||||
throw new PasteFailedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String postData(Map<String, String> data) throws PasteFailedException {
|
||||
try {
|
||||
String stringJSON = this.exec(encodeData(data), ContentType.JSON);
|
||||
return "https://paste.gg/" + ((JSONObject) ((JSONObject) new JSONParser().parse(stringJSON)).get("result")).get("id");
|
||||
} catch (IOException | ParseException e) {
|
||||
throw new PasteFailedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsMultiFile() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,63 +1,52 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An interface to a web-based text-pasting service. Classes implementing this
|
||||
* interface should implement its methods to send data to an online text-sharing
|
||||
* service, such as pastebin.com. Conventionally, a paste is accomplished by (given
|
||||
* some PasteService instance ps):
|
||||
* An interface to a web-based text-pasting service. Classes extending this
|
||||
* should implement its methods to send data to an online text-sharing service,
|
||||
* such as pastebin.com. Given some PasteService instance ps, a paste is accomplished by:
|
||||
*
|
||||
* {@code ps.postData(ps.encodeData(someString), ps.getPostURL());}
|
||||
* {@code ps.postData(someString);}
|
||||
*
|
||||
* Services that provide a distinction between "public" and "private" pastes
|
||||
* should implement a custom constructor that specifies which kind the PasteService
|
||||
* should implement a constructor that specifies which kind the PasteService
|
||||
* instance is submitting; an example of this is the PastebinPasteService class.
|
||||
*/
|
||||
public interface PasteService {
|
||||
public abstract class PasteService extends HttpAPIClient {
|
||||
PasteService(String url) {
|
||||
super(url);
|
||||
}
|
||||
|
||||
PasteService(String url, String accessToken) {
|
||||
super(url, accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given String data into a format suitable for transmission in an HTTP request.
|
||||
* Post data to the Web.
|
||||
*
|
||||
* @param data The raw data to encode.
|
||||
* @return A URL-encoded string.
|
||||
*/
|
||||
String encodeData(String data);
|
||||
|
||||
/**
|
||||
* Encode the given Map data into a format suitable for transmission in an HTTP request.
|
||||
*
|
||||
* @param data The raw data to encode.
|
||||
* @return A URL-encoded string.
|
||||
*/
|
||||
String encodeData(Map<String, String> data);
|
||||
|
||||
/**
|
||||
* Get the URL to which this paste service sends new pastes.
|
||||
*
|
||||
* @return The URL that will be accessed to complete the paste.
|
||||
*/
|
||||
URL getPostURL();
|
||||
|
||||
/**
|
||||
* Post encoded data to the Web.
|
||||
*
|
||||
* @param encodedData A URL-encoded String containing the full request to post to
|
||||
* the given URL. Can be the result of calling #encodeData().
|
||||
* @param url The URL to which to paste. Can be the result of calling #getPostURL().
|
||||
* @param data A String to post to the web.
|
||||
* @throws PasteFailedException When pasting/posting the data failed.
|
||||
* @return The URL at which the new paste is visible.
|
||||
*/
|
||||
String postData(String encodedData, URL url) throws PasteFailedException;
|
||||
public abstract String postData(String data) throws PasteFailedException;
|
||||
|
||||
/**
|
||||
* Post data to the Web.
|
||||
*
|
||||
* @param data A Map to post to the web.
|
||||
* @throws PasteFailedException When pasting/posting the data failed.
|
||||
* @return The URL at which the new paste is visible.
|
||||
*/
|
||||
public abstract String postData(Map<String, String> data) throws PasteFailedException;
|
||||
|
||||
/**
|
||||
* Does this service support uploading multiple files.
|
||||
*
|
||||
* Newer services like gist support multi-file which allows us to upload configs
|
||||
* in addition to the standard logs.
|
||||
* Newer services like GitHub's Gist support multi-file pastes,
|
||||
* which allows us to upload configs in addition to the standard logs.
|
||||
*
|
||||
* @return True if this service supports multiple file upload.
|
||||
*/
|
||||
boolean supportsMultiFile();
|
||||
public abstract boolean supportsMultiFile();
|
||||
}
|
||||
+3
-1
@@ -14,12 +14,14 @@ public class PasteServiceFactory {
|
||||
*/
|
||||
public static PasteService getService(PasteServiceType type, boolean isPrivate) {
|
||||
switch(type) {
|
||||
case PASTEGG:
|
||||
return new PasteGGPasteService(isPrivate);
|
||||
case PASTEBIN:
|
||||
return new PastebinPasteService(isPrivate);
|
||||
case HASTEBIN:
|
||||
return new HastebinPasteService();
|
||||
case GITHUB:
|
||||
return new GithubPasteService(isPrivate);
|
||||
return new GitHubPasteService(isPrivate);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
* @see PasteServiceFactory
|
||||
*/
|
||||
public enum PasteServiceType {
|
||||
/**
|
||||
* @see PasteGGPasteService
|
||||
*/
|
||||
PASTEGG,
|
||||
/**
|
||||
* @see PastebinPasteService
|
||||
*/
|
||||
@@ -16,7 +20,7 @@ public enum PasteServiceType {
|
||||
*/
|
||||
HASTEBIN,
|
||||
/**
|
||||
* @see GithubPasteService
|
||||
* @see GitHubPasteService
|
||||
*/
|
||||
GITHUB
|
||||
}
|
||||
+35
-59
@@ -1,24 +1,19 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Pastes to {@code pastebin.com}.
|
||||
*/
|
||||
public class PastebinPasteService implements PasteService {
|
||||
class PastebinPasteService extends PasteService {
|
||||
private final boolean isPrivate;
|
||||
private static final String PASTEBIN_POST_REQUEST = "https://pastebin.com/api/api_post.php";
|
||||
|
||||
private boolean isPrivate;
|
||||
|
||||
public PastebinPasteService(boolean isPrivate) {
|
||||
PastebinPasteService(boolean isPrivate) {
|
||||
super(PASTEBIN_POST_REQUEST);
|
||||
this.isPrivate = isPrivate;
|
||||
}
|
||||
|
||||
@@ -26,73 +21,54 @@ public class PastebinPasteService implements PasteService {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public URL getPostURL() {
|
||||
String encodeData(String data) {
|
||||
try {
|
||||
return new URL("http://pastebin.com/api/api_post.php");
|
||||
} catch (MalformedURLException e) {
|
||||
return null; // should never hit here
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String encodeData(String data) {
|
||||
try {
|
||||
String encData = URLEncoder.encode("api_dev_key", "UTF-8") + "=" + URLEncoder.encode("d61d68d31e8e0392b59b50b277411c71", "UTF-8");
|
||||
encData += "&" + URLEncoder.encode("api_option", "UTF-8") + "=" + URLEncoder.encode("paste", "UTF-8");
|
||||
encData += "&" + URLEncoder.encode("api_paste_code", "UTF-8") + "=" + URLEncoder.encode(data, "UTF-8");
|
||||
encData += "&" + URLEncoder.encode("api_paste_private", "UTF-8") + "=" + URLEncoder.encode(this.isPrivate ? "1" : "0", "UTF-8");
|
||||
encData += "&" + URLEncoder.encode("api_paste_format", "UTF-8") + "=" + URLEncoder.encode("yaml", "UTF-8");
|
||||
return encData;
|
||||
return URLEncoder.encode("api_dev_key", "UTF-8") + "=" + URLEncoder.encode("d61d68d31e8e0392b59b50b277411c71", "UTF-8") +
|
||||
"&" + URLEncoder.encode("api_option", "UTF-8") + "=" + URLEncoder.encode("paste", "UTF-8") +
|
||||
"&" + URLEncoder.encode("api_paste_code", "UTF-8") + "=" + URLEncoder.encode(data, "UTF-8") +
|
||||
"&" + URLEncoder.encode("api_paste_private", "UTF-8") + "=" + URLEncoder.encode(this.isPrivate ? "1" : "0", "UTF-8") +
|
||||
"&" + URLEncoder.encode("api_paste_format", "UTF-8") + "=" + URLEncoder.encode("yaml", "UTF-8") +
|
||||
"&" + URLEncoder.encode("api_paste_name", "UTF-8") + "=" + URLEncoder.encode("Multiverse-Core Debug Info", "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return ""; // should never hit here
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String encodeData(Map<String, String> data) {
|
||||
return null;
|
||||
String encodeData(Map<String, String> data) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String postData(String encodedData, URL url) throws PasteFailedException {
|
||||
OutputStreamWriter wr = null;
|
||||
BufferedReader rd = null;
|
||||
public String postData(String data) throws PasteFailedException {
|
||||
try {
|
||||
URLConnection conn = url.openConnection();
|
||||
conn.setDoOutput(true);
|
||||
wr = new OutputStreamWriter(conn.getOutputStream());
|
||||
wr.write(encodedData);
|
||||
wr.flush();
|
||||
|
||||
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String line;
|
||||
String pastebinUrl = "";
|
||||
while ((line = rd.readLine()) != null) {
|
||||
pastebinUrl = line;
|
||||
}
|
||||
return pastebinUrl;
|
||||
} catch (Exception e) {
|
||||
return this.exec(encodeData(data), ContentType.URLENCODED);
|
||||
} catch (IOException e) {
|
||||
throw new PasteFailedException(e);
|
||||
} finally {
|
||||
if (wr != null) {
|
||||
try {
|
||||
wr.close();
|
||||
} catch (IOException ignore) { }
|
||||
}
|
||||
if (rd != null) {
|
||||
try {
|
||||
rd.close();
|
||||
} catch (IOException ignore) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String postData(Map<String, String> data) throws PasteFailedException {
|
||||
try {
|
||||
return this.exec(encodeData(data), ContentType.URLENCODED);
|
||||
} catch (IOException e) {
|
||||
throw new PasteFailedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsMultiFile() {
|
||||
return false;
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
/**
|
||||
* URL-Shortener.
|
||||
* An interface to a web-based URL Shortener. Classes extending this should
|
||||
* implement its methods to shorten links using the service. Given some
|
||||
* URLShortener instance us, a URL is shortened by:
|
||||
*
|
||||
* {@code us.shorten(longUrl);}
|
||||
*
|
||||
* An example of this, is the BitlyURLShortener.
|
||||
*/
|
||||
public interface URLShortener {
|
||||
public abstract class URLShortener extends HttpAPIClient {
|
||||
URLShortener(String url) {
|
||||
super(url);
|
||||
}
|
||||
|
||||
URLShortener(String url, String accessToken) {
|
||||
super(url, accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorten an URL.
|
||||
* Shorten a URL.
|
||||
* @param longUrl The long form.
|
||||
* @return The shortened URL.
|
||||
*/
|
||||
String shorten(String longUrl);
|
||||
public abstract String shorten(String longUrl);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
/**
|
||||
* Used to construct {@link URLShortener}s.
|
||||
*/
|
||||
public class URLShortenerFactory {
|
||||
private URLShortenerFactory() { }
|
||||
|
||||
/**
|
||||
* Constructs a new {@link URLShortener}.
|
||||
* @param type The {@link URLShortenerType}.
|
||||
* @return The newly created {@link URLShortener}.
|
||||
*/
|
||||
public static URLShortener getService(URLShortenerType type) {
|
||||
if (type == URLShortenerType.BITLY) {
|
||||
try {
|
||||
return new BitlyURLShortener();
|
||||
} catch (UnsupportedOperationException ignored) {}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||
|
||||
/**
|
||||
* An enum containing all known {@link URLShortener}s.
|
||||
*
|
||||
* @see URLShortener
|
||||
* @see URLShortenerFactory
|
||||
*/
|
||||
public enum URLShortenerType {
|
||||
/**
|
||||
* @see BitlyURLShortener
|
||||
*/
|
||||
BITLY
|
||||
}
|
||||
+64
-113
@@ -1,7 +1,8 @@
|
||||
name: Multiverse-Core
|
||||
main: com.onarandombox.MultiverseCore.MultiverseCore
|
||||
authors: ['Rigby', 'fernferret', 'lithium3141', 'main--', 'dumptruckman']
|
||||
authors: ['dumptruckman', 'Rigby', 'fernferret', 'lithium3141', 'main--']
|
||||
website: 'https://dev.bukkit.org/projects/multiverse-core'
|
||||
softdepend: ['Vault']
|
||||
api-version: 1.13
|
||||
version: maven-version-number
|
||||
commands:
|
||||
@@ -10,34 +11,24 @@ commands:
|
||||
usage: /<command>
|
||||
mvcreate:
|
||||
description: World create command
|
||||
usage: |
|
||||
/<command> <world> <environment>
|
||||
/<command> creative normal -- Creates a world called 'creative' with a NORMAL environment.
|
||||
/<command> hellworld nether -- Creates a world called 'hellworld' with a NETHER environment.
|
||||
mvc:
|
||||
description: World create command
|
||||
aliases: [mvc]
|
||||
usage: |
|
||||
/<command> <world> <environment>
|
||||
/<command> creative normal -- Creates a world called 'creative' with a NORMAL environment.
|
||||
/<command> hellworld nether -- Creates a world called 'hellworld' with a NETHER environment.
|
||||
mvimport:
|
||||
description: World import command
|
||||
aliases: [mvim]
|
||||
usage: |
|
||||
/<command> <world> <environment>
|
||||
/<command> creative normal -- Imports an existing world called 'creative' with a NORMAL environment.
|
||||
/<command> hellworld nether -- Imports an existing world called 'hellworld' with a NETHER environment.
|
||||
mvim:
|
||||
description: World import command
|
||||
usage: |
|
||||
/<command> <world> <environment>
|
||||
/<command> creative normal -- Imports an existing world called 'creative' with a NORMAL environment.
|
||||
/<command> hellworld nether -- Imports an existing world called 'hellworld' with a NETHER environment.
|
||||
/<command> <world> <environment> [-g generator[:id]] [-n]
|
||||
/<command> creative normal -- Imports an existing world called 'creative' with a NORMAL environment.
|
||||
/<command> hellworld nether -- Imports an existing world called 'hellworld' with a NETHER environment.
|
||||
mvremove:
|
||||
description: World remove command
|
||||
description: Remove world from multiverse command
|
||||
usage: |
|
||||
/<command> <world>
|
||||
mvdelete:
|
||||
description: World delete command
|
||||
description: Delete world from server folders command
|
||||
usage: |
|
||||
/<command> <world>
|
||||
mvunload:
|
||||
@@ -46,103 +37,75 @@ commands:
|
||||
/<command> <world>
|
||||
mvmodify:
|
||||
description: Modify the settings of an existing world
|
||||
aliases: [mvm]
|
||||
usage: |
|
||||
/<command> <world> <option>:<value>
|
||||
/<command> creative pvp:false -- Turns off PVP in the 'creative' world.
|
||||
/<command> <set|add|remove|clear> <value> <property> [world]
|
||||
/<command> set pvp false creative -- Turns off PVP in the 'creative' world.
|
||||
mvmset:
|
||||
description: Modify the settings of an existing world
|
||||
usage: |
|
||||
/<command> <world> <option>:<value>
|
||||
/<command> creative pvp:false -- Turns off PVP in the 'creative' world.
|
||||
/<command> <value> <property> [world]
|
||||
/<command> pvp false creative -- Turns off PVP in the 'creative' world.
|
||||
mvmadd:
|
||||
description: Modify the settings of an existing world
|
||||
usage: |
|
||||
/<command> <world> <option>:<value>
|
||||
/<command> creative pvp:false -- Turns off PVP in the 'creative' world.
|
||||
/<command> <value> <property> [world]
|
||||
/<command> sheep animals world_nether -- Add sheep to animal list for 'world_nether' world.
|
||||
mvmremove:
|
||||
description: Modify the settings of an existing world
|
||||
aliases: [mvmdelete]
|
||||
usage: |
|
||||
/<command> <world> <option>:<value>
|
||||
/<command> creative pvp:false -- Turns off PVP in the 'creative' world.
|
||||
/<command> <value> <property> [world]
|
||||
/<command> sheep animals world_nether -- remove sheep from animal list for 'world_nether' world.
|
||||
mvmclear:
|
||||
description: Modify the settings of an existing world
|
||||
usage: |
|
||||
/<command> <world> <option>:<value>
|
||||
/<command> creative pvp:false -- Turns off PVP in the 'creative' world.
|
||||
mvm:
|
||||
description: Modify the settings of an existing world
|
||||
usage: |
|
||||
/<command> <world> <option>:<value>
|
||||
/<command> creative pvp:false -- Turns off PVP in the 'creative' world.
|
||||
/<command> <property> [world]
|
||||
/<command> animals world_nether -- Empties animal list for 'world_nether' world.
|
||||
mvtp:
|
||||
description: Command to teleport between Worlds
|
||||
usage: |
|
||||
/<command> <world>[:spawn]
|
||||
/<command> [player] <destination>
|
||||
Example: /<command> creative - Teleports you to the relevant location in the 'creative' world.
|
||||
Example: /<command> creative:spawn - Teleports you to the spawn of the 'creative' world.
|
||||
mvlist:
|
||||
description: Print list of loaded Worlds
|
||||
aliases: [mvl]
|
||||
usage: |
|
||||
/<command> [environment]
|
||||
Example: /<command> NETHER - Shows all NETHER Worlds.
|
||||
Example: /<command> NORMAL - Shows all NORMAL Worlds.
|
||||
mvl:
|
||||
description: Print list of loaded Worlds
|
||||
usage: |
|
||||
/<command> [environment]
|
||||
/<command> [page]
|
||||
Example: /<command> NETHER - Shows all NETHER Worlds.
|
||||
Example: /<command> NORMAL - Shows all NORMAL Worlds.
|
||||
mvsetspawn:
|
||||
description: Set the spawn area for a particular world
|
||||
usage: /<command> -- Sets the spawn area of the current world to your location.
|
||||
mvset:
|
||||
description: Set the spawn area for a particular world
|
||||
usage: /<command> -- Sets the spawn area of the current world to your location.
|
||||
mvss:
|
||||
description: Set the spawn area for a particular world
|
||||
aliases: [mvsets, mvss]
|
||||
usage: /<command> -- Sets the spawn area of the current world to your location.
|
||||
mvspawn:
|
||||
description: Teleport to the spawn area
|
||||
usage: /<command> -- Teleports you to the spawn area of your current world.
|
||||
mvs:
|
||||
description: Teleport to the spawn area
|
||||
usage: /<command> -- Teleports you to the spawn area of your current world.
|
||||
aliases: [mvs]
|
||||
usage: /<command> [player] -- Teleports you to the spawn area of your current world.
|
||||
mvcoord:
|
||||
description: Display World, Coordinates, Direction & Compression for a world.
|
||||
usage: |
|
||||
/<command> [world]
|
||||
/<command> -- Shows the relevant coordinates in your current world.
|
||||
/<command> creative -- Shows the relevant coordinates if you were in the 'creative' world.
|
||||
mvc:
|
||||
description: Display World, Coordinates, Direction & Compression for a world.
|
||||
aliases: [mvco]
|
||||
usage: |
|
||||
/<command> [world]
|
||||
/<command> -- Shows the relevant coordinates in your current world.
|
||||
/<command> creative -- Shows the relevant coordinates if you were in the 'creative' world.
|
||||
mvwho:
|
||||
description: Display online users per world.
|
||||
aliases: [mvw]
|
||||
usage: |
|
||||
/<command> [world]
|
||||
/<command> -- Shows who is online in each world.
|
||||
/<command> creative -- Shows who is online in the 'creative' world.
|
||||
mvw:
|
||||
description: Display online users per world.
|
||||
usage: |
|
||||
/<command> [world]
|
||||
/<command> [world|--all]
|
||||
/<command> -- Shows who is online in each world.
|
||||
/<command> creative -- Shows who is online in the 'creative' world.
|
||||
mvreload:
|
||||
description: Reload Configuration files.
|
||||
usage: /<command>
|
||||
mvr:
|
||||
description: Reload Configuration files.
|
||||
aliases: [mvr]
|
||||
usage: /<command>
|
||||
mvpurge:
|
||||
description: Purge the targetted world of creatures.
|
||||
usage: |
|
||||
/<command> [world] [creatures]
|
||||
/<command> [WORLD|all] [all|animals|monsters|MOBNAME]
|
||||
/<command> -- Purges the players world of all creatures.
|
||||
/<command> creative * -- Purges the creative world of all Creatures.
|
||||
/<command> creative all -- Purges the creative world of all Creatures.
|
||||
/<command> creative creeper -- Purges the creative world of all CREEPERS.
|
||||
mvconfirm:
|
||||
description: Confirms sensitive decisions like deleting a world.
|
||||
@@ -150,87 +113,75 @@ commands:
|
||||
/<command>
|
||||
mvinfo:
|
||||
description: Gets world info.
|
||||
aliases: [mvi]
|
||||
usage: |
|
||||
/<command> [world]
|
||||
mvi:
|
||||
description: Gets world info.
|
||||
usage: |
|
||||
/<command> [world]
|
||||
/<command> [world] [page]
|
||||
mvenv:
|
||||
description: Tells the user all possible environment types.
|
||||
usage: |
|
||||
/<command>
|
||||
mvv:
|
||||
description: Prints out version info.
|
||||
usage: |
|
||||
/<command>
|
||||
mvversion:
|
||||
description: Prints out version info.
|
||||
aliases: [mvv, mvver]
|
||||
usage: |
|
||||
/<command>
|
||||
mvco:
|
||||
description: Displays the player's coordinates.
|
||||
usage: |
|
||||
/<command>
|
||||
mvh:
|
||||
description: Displays the Multiverse Help.
|
||||
usage: |
|
||||
/<command>
|
||||
mvsearch:
|
||||
description: Displays the Multiverse Help.
|
||||
usage: |
|
||||
/<command>
|
||||
/<command> [-b|-h|-p] [--include-plugin-list]
|
||||
mvhelp:
|
||||
description: Displays the Multiverse Help.
|
||||
aliases: [mvsearch, mvh]
|
||||
usage: |
|
||||
/<command>
|
||||
/<command> [filter] [page #]
|
||||
mvdebug:
|
||||
description: Turns on debugging.
|
||||
usage: |
|
||||
/<command>
|
||||
/<command> [1|2|3|off|silent]
|
||||
mvgenerators:
|
||||
description: Displays all found world generators.
|
||||
usage: |
|
||||
/<command>
|
||||
mvgens:
|
||||
description: Displays all found world generators.
|
||||
aliases: [mvgens]
|
||||
usage: |
|
||||
/<command>
|
||||
mvload:
|
||||
description: Loads a world into Multiverse.
|
||||
usage: |
|
||||
/<command> {WORLD}
|
||||
/<command> <world>
|
||||
mvregen:
|
||||
description: Regenerates a world Multiverse already knows about.
|
||||
usage: |
|
||||
/<command> {WORLD}
|
||||
/<command> <world> [-s seed]
|
||||
mvscript:
|
||||
description: Runs a script from the Multiverse scripts directory.
|
||||
usage: |
|
||||
/<command> {script} [target]
|
||||
/<command> <script> [target]
|
||||
mvclone:
|
||||
description: World clone command
|
||||
aliases: [mvcl]
|
||||
usage: |
|
||||
/<command> <world> <environment>
|
||||
/<command> <world> <environment> [-g generator[:id]]
|
||||
/<command> creative grieftastic -- Creates a world called 'grieftastic' exactly identical to the world 'creative'.
|
||||
mvsilent:
|
||||
description: Reduces startup messages
|
||||
usage: |
|
||||
/<command> [true|false]
|
||||
|
||||
mvgamerule:
|
||||
description: Sets a gamerule.
|
||||
aliases: [mvrule]
|
||||
usage: |
|
||||
/<command> {RULE} {VALUE} [WORLD]
|
||||
mvrule:
|
||||
description: Sets a gamerule.
|
||||
usage: |
|
||||
/<command> {RULE} {VALUE} [WORLD]
|
||||
/<command> <rule> <value> [world]
|
||||
mvgamerules:
|
||||
description: Lists the gamerules.
|
||||
description: Lists the gamerules
|
||||
aliases: [mvrules]
|
||||
usage: |
|
||||
/<command> [WORLD]
|
||||
mvrules:
|
||||
description: Lists the gamerules.
|
||||
/<command> [world]
|
||||
mvanchors:
|
||||
description: Creating and removing Anchors command
|
||||
aliases: [mvanchor]
|
||||
usage: |
|
||||
/<command> [WORLD]
|
||||
/<command> <name> [-d]
|
||||
mvcheck:
|
||||
description: Validate your multiverse settings command
|
||||
usage: |
|
||||
/<command> <name> <destination>
|
||||
mvconfig:
|
||||
description: Configuration command
|
||||
aliases: [mvconf]
|
||||
usage: |
|
||||
/<command> <property> <value>
|
||||
@@ -6,6 +6,9 @@ import static org.junit.Assert.assertTrue;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import org.junit.After;
|
||||
@@ -86,6 +89,34 @@ public class FileUtilsTest {
|
||||
assertTrue(Files.isRegularFile(targetChildDirFile));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void copyFolder_excludingSomeFiles() throws Exception {
|
||||
Path targetDir = tempDir.resolve("target");
|
||||
Path targetFile = targetDir.resolve("parentDirFile.txt");
|
||||
Path targetIgnoreFile = targetDir.resolve("parentIgnoreFile.txt");
|
||||
Path targetChildDir = targetDir.resolve("childDir");
|
||||
Path targetChildDirFile = targetChildDir.resolve("childDirFile.txt");
|
||||
Path targetChildIgnoreFile = targetChildDir.resolve("childIgnoreFile.txt");
|
||||
|
||||
List<String> excludeFiles = new ArrayList<>(Arrays.asList("parentIgnoreFile.txt", "childIgnoreFile.txt"));
|
||||
|
||||
assertFalse(Files.isDirectory(targetDir));
|
||||
assertFalse(Files.isRegularFile(targetFile));
|
||||
assertFalse(Files.isRegularFile(targetIgnoreFile));
|
||||
assertFalse(Files.isDirectory(targetChildDir));
|
||||
assertFalse(Files.isRegularFile(targetChildDirFile));
|
||||
assertFalse(Files.isRegularFile(targetChildIgnoreFile));
|
||||
|
||||
assertTrue(FileUtils.copyFolder(parentDir.toFile(), targetDir.toFile(), excludeFiles, Logging.getLogger()));
|
||||
|
||||
assertTrue(Files.isDirectory(targetDir));
|
||||
assertTrue(Files.isRegularFile(targetFile));
|
||||
assertFalse(Files.isRegularFile(targetIgnoreFile));
|
||||
assertTrue(Files.isDirectory(targetChildDir));
|
||||
assertTrue(Files.exists(targetChildDirFile));
|
||||
assertFalse(Files.isRegularFile(targetChildIgnoreFile));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void copyFolder_intoExistingFolder() throws Exception {
|
||||
Path targetDir = Files.createDirectory(tempDir.resolve("target"));
|
||||
|
||||
Reference in new issue
Block a user