mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-12-27 11:37:52 +01:00
Make it build and add safety to tab completion times
This commit is contained in:
parent
98e85733b9
commit
a693d23489
@ -99,9 +99,8 @@ subprojects {
|
|||||||
maven {url "http://repo.dmulloy2.net/content/groups/public/"}
|
maven {url "http://repo.dmulloy2.net/content/groups/public/"}
|
||||||
maven {url "https://repo.destroystokyo.com/repository/maven-public//"}
|
maven {url "https://repo.destroystokyo.com/repository/maven-public//"}
|
||||||
//maven {url "http://ci.emc.gs/nexus/content/groups/aikar/" }
|
//maven {url "http://ci.emc.gs/nexus/content/groups/aikar/" }
|
||||||
maven {url "http://ci.athion.net/job/PlotSquared-Legacy/ws/mvn/"}
|
maven {url "https://ci.athion.net/plugin/repository/tools/"}
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
maven {url "http://empcraft.com/maven2"}
|
|
||||||
maven {url "https://hub.spigotmc.org/nexus/content/groups/public/"}
|
maven {url "https://hub.spigotmc.org/nexus/content/groups/public/"}
|
||||||
maven {url "https://maven.enginehub.org/repo/"}
|
maven {url "https://maven.enginehub.org/repo/"}
|
||||||
maven {url "https://repo.maven.apache.org/maven2"}
|
maven {url "https://repo.maven.apache.org/maven2"}
|
||||||
@ -111,6 +110,9 @@ subprojects {
|
|||||||
maven {url "https://repo.inventivetalent.org/content/groups/public/"}
|
maven {url "https://repo.inventivetalent.org/content/groups/public/"}
|
||||||
maven {url "https://store.ttyh.ru/libraries/"}
|
maven {url "https://store.ttyh.ru/libraries/"}
|
||||||
maven {url "https://repo.dmulloy2.net/nexus/repository/public/"}
|
maven {url "https://repo.dmulloy2.net/nexus/repository/public/"}
|
||||||
|
maven {url "http://maven.elmakers.com/repository/"}
|
||||||
|
maven {url "https://ci.ender.zone/plugin/repository/everything/"}
|
||||||
|
maven {url "https://plotsquared.com/mvn/"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
task aggregatedJavadocs(type: Javadoc, description: 'Generate javadocs from all child projects as if it was a single project', group: 'Documentation') {
|
task aggregatedJavadocs(type: Javadoc, description: 'Generate javadocs from all child projects as if it was a single project', group: 'Documentation') {
|
||||||
|
@ -7,17 +7,17 @@ dependencies {
|
|||||||
compile('com.destroystokyo.paper:paper-api:1.12-R0.1-SNAPSHOT') {
|
compile('com.destroystokyo.paper:paper-api:1.12-R0.1-SNAPSHOT') {
|
||||||
exclude group: 'net.md-5'
|
exclude group: 'net.md-5'
|
||||||
}
|
}
|
||||||
compile 'org.bukkit.craftbukkitv1_10:craftbukkitv1_10:1.10'
|
compile 'org.bukkit.craftbukkit:Craftbukkit_1_12:1.12.1'
|
||||||
compile 'org.bukkit.craftbukkitv1_11:Craftbukkit:1.11'
|
compile 'org.bukkit.craftbukkit:Craftbukkit_1_11:1.11'
|
||||||
// compile 'org.bukkit.craftbukkitv1_12:Craftbukkit:1.12'
|
compile 'org.bukkit.craftbukkit:Craftbukkit_1_10:1.10'
|
||||||
compile 'org.bukkit.craftbukkitv1_12_R1:Craftbukkit:1.12.1'
|
compile 'org.bukkit.craftbukkit:Craftbukkit_1_9:1.9.4'
|
||||||
|
compile 'org.bukkit.craftbukkit:Craftbukkit_1_8:1.8.8'
|
||||||
|
compile 'org.bukkit.craftbukkit:Craftbukkit_1_7:1.7.10'
|
||||||
compile 'net.milkbowl.vault:VaultAPI:1.5.6'
|
compile 'net.milkbowl.vault:VaultAPI:1.5.6'
|
||||||
compile 'com.massivecraft:factions:2.8.0'
|
compile 'com.massivecraft:factions:2.8.0'
|
||||||
compile 'com.drtshock:factions:1.6.9.5'
|
|
||||||
compile 'com.factionsone:FactionsOne:1.2.2'
|
compile 'com.factionsone:FactionsOne:1.2.2'
|
||||||
compile 'me.ryanhamshire:GriefPrevention:11.5.2'
|
compile 'me.ryanhamshire:GriefPrevention:11.5.2'
|
||||||
compile 'com.massivecraft:mcore:7.0.1'
|
compile 'com.massivecraft:mcore:7.0.1'
|
||||||
compile 'net.sacredlabyrinth.Phaed:PreciousStones:10.0.4-SNAPSHOT'
|
|
||||||
compile 'net.jzx7:regios:5.9.9'
|
compile 'net.jzx7:regios:5.9.9'
|
||||||
compile 'com.bekvon.bukkit.residence:Residence:4.5._13.1'
|
compile 'com.bekvon.bukkit.residence:Residence:4.5._13.1'
|
||||||
compile 'com.palmergames.bukkit:towny:0.84.0.9'
|
compile 'com.palmergames.bukkit:towny:0.84.0.9'
|
||||||
@ -26,9 +26,6 @@ dependencies {
|
|||||||
compile 'com.sk89q.worldedit:worldedit-bukkit:6.1.4-SNAPSHOT'
|
compile 'com.sk89q.worldedit:worldedit-bukkit:6.1.4-SNAPSHOT'
|
||||||
compile 'com.sk89q.worldedit:worldedit-core:6.1.4-SNAPSHOT'
|
compile 'com.sk89q.worldedit:worldedit-core:6.1.4-SNAPSHOT'
|
||||||
compile 'com.thevoxelbox.voxelsniper:voxelsniper:5.171.0'
|
compile 'com.thevoxelbox.voxelsniper:voxelsniper:5.171.0'
|
||||||
compile 'org.bukkit.craftbukkit.v1_9R2:craftbukkitv1_9R2:1.9.4'
|
|
||||||
compile 'org.bukkit.craftbukkit:Craftbukkit:1.7.10'
|
|
||||||
compile 'org.bukkit.craftbukkit:CraftBukkit:1.8.8'
|
|
||||||
compile 'com.comphenix.protocol:ProtocolLib-API:4.4.0'
|
compile 'com.comphenix.protocol:ProtocolLib-API:4.4.0'
|
||||||
compile 'com.wasteofplastic:askyblock:3.0.8.2'
|
compile 'com.wasteofplastic:askyblock:3.0.8.2'
|
||||||
compile('org.inventivetalent:mapmanager:1.7.2-SNAPSHOT') {
|
compile('org.inventivetalent:mapmanager:1.7.2-SNAPSHOT') {
|
||||||
@ -100,4 +97,4 @@ shadowJar.doLast {
|
|||||||
ant.checksum file: task.archivePath
|
ant.checksum file: task.archivePath
|
||||||
}
|
}
|
||||||
|
|
||||||
build.dependsOn(shadowJar);
|
build.dependsOn(shadowJar);
|
||||||
|
@ -517,16 +517,10 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
Fawe.debug("Plugin 'Factions' found. Using it now.");
|
Fawe.debug("Plugin 'Factions' found. Using it now.");
|
||||||
} catch (final Throwable e) {
|
} catch (final Throwable e) {
|
||||||
try {
|
try {
|
||||||
managers.add(new FactionsUUIDFeature(factionsPlugin, this));
|
managers.add(new FactionsOneFeature(factionsPlugin, this));
|
||||||
Fawe.debug("Plugin 'FactionsUUID' found. Using it now.");
|
Fawe.debug("Plugin 'FactionsUUID' found. Using it now.");
|
||||||
} catch (Throwable e2) {
|
} catch (Throwable e3) {
|
||||||
try {
|
MainUtil.handleError(e);
|
||||||
managers.add(new FactionsOneFeature(factionsPlugin, this));
|
|
||||||
Fawe.debug("Plugin 'FactionsUUID' found. Using it now.");
|
|
||||||
} catch (Throwable e3) {
|
|
||||||
MainUtil.handleError(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -548,16 +542,6 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Plugin preciousstonesPlugin = Bukkit.getServer().getPluginManager().getPlugin("PreciousStones");
|
|
||||||
if ((preciousstonesPlugin != null) && preciousstonesPlugin.isEnabled()) {
|
|
||||||
try {
|
|
||||||
managers.add(new PreciousStonesFeature(preciousstonesPlugin, this));
|
|
||||||
Fawe.debug("Plugin 'PreciousStones' found. Using it now.");
|
|
||||||
} catch (final Throwable e) {
|
|
||||||
MainUtil.handleError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
final Plugin aSkyBlock = Bukkit.getServer().getPluginManager().getPlugin("ASkyBlock");
|
final Plugin aSkyBlock = Bukkit.getServer().getPluginManager().getPlugin("ASkyBlock");
|
||||||
if ((aSkyBlock != null) && aSkyBlock.isEnabled()) {
|
if ((aSkyBlock != null) && aSkyBlock.isEnabled()) {
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
package com.boydti.fawe.bukkit.regions;
|
|
||||||
|
|
||||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
|
||||||
import com.boydti.fawe.object.RegionWrapper;
|
|
||||||
import com.boydti.fawe.util.Perm;
|
|
||||||
import com.massivecraft.factions.Board;
|
|
||||||
import com.massivecraft.factions.FLocation;
|
|
||||||
import com.massivecraft.factions.Faction;
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
|
|
||||||
public class FactionsUUIDFeature extends BukkitMaskManager implements Listener {
|
|
||||||
private final Board instance;
|
|
||||||
|
|
||||||
public FactionsUUIDFeature(final Plugin factionsPlugin, final FaweBukkit p3) {
|
|
||||||
super(factionsPlugin.getName());
|
|
||||||
this.instance = Board.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BukkitMask getMask(final FawePlayer<Player> fp, MaskType type) {
|
|
||||||
final Player player = fp.parent;
|
|
||||||
final Chunk chunk = player.getLocation().getChunk();
|
|
||||||
final boolean perm = Perm.hasPermission(FawePlayer.wrap(player), "fawe.factions.wilderness");
|
|
||||||
final World world = player.getWorld();
|
|
||||||
|
|
||||||
RegionWrapper locs = new RegionWrapper(chunk.getX(), chunk.getX(), chunk.getZ(), chunk.getZ());
|
|
||||||
|
|
||||||
int count = 32;
|
|
||||||
|
|
||||||
if (this.isAdded(locs, world, player, perm, type)) {
|
|
||||||
boolean hasPerm = true;
|
|
||||||
|
|
||||||
RegionWrapper chunkSelection;
|
|
||||||
while (hasPerm && (count > 0)) {
|
|
||||||
count--;
|
|
||||||
|
|
||||||
hasPerm = false;
|
|
||||||
|
|
||||||
chunkSelection = new RegionWrapper(locs.maxX + 1, locs.maxX + 1, locs.minZ, locs.maxZ);
|
|
||||||
|
|
||||||
if (this.isAdded(chunkSelection, world, player, perm, type)) {
|
|
||||||
locs = new RegionWrapper(locs.minX, locs.maxX + 1, locs.minZ, locs.maxZ);
|
|
||||||
hasPerm = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunkSelection = new RegionWrapper(locs.minX - 1, locs.minX - 1, locs.minZ, locs.maxZ);
|
|
||||||
|
|
||||||
if (this.isAdded(chunkSelection, world, player, perm, type)) {
|
|
||||||
locs = new RegionWrapper(locs.minX - 1, locs.maxX, locs.minZ, locs.maxZ);
|
|
||||||
hasPerm = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunkSelection = new RegionWrapper(locs.minX, locs.maxX, locs.maxZ + 1, locs.maxZ + 1);
|
|
||||||
|
|
||||||
if (this.isAdded(chunkSelection, world, player, perm, type)) {
|
|
||||||
locs = new RegionWrapper(locs.minX, locs.maxX, locs.minZ, locs.maxZ + 1);
|
|
||||||
hasPerm = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunkSelection = new RegionWrapper(locs.minX, locs.maxX, locs.minZ - 1, locs.minZ - 1);
|
|
||||||
|
|
||||||
if (this.isAdded(chunkSelection, world, player, perm, type)) {
|
|
||||||
locs = new RegionWrapper(locs.minX, locs.maxX, locs.minZ - 1, locs.maxZ);
|
|
||||||
hasPerm = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final Location pos1 = new Location(world, locs.minX << 4, 1, locs.minZ << 4);
|
|
||||||
final Location pos2 = new Location(world, 15 + (locs.maxX << 4), 256, 15 + (locs.maxZ << 4));
|
|
||||||
return new BukkitMask(pos1, pos2) {
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "CHUNK:" + pos1.getChunk().getX() + "," + pos1.getChunk().getZ();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAdded(final RegionWrapper locs, final World world, final Player player, final boolean perm, MaskType type) {
|
|
||||||
for (int x = locs.minX; x <= locs.maxX; x++) {
|
|
||||||
for (int z = locs.minZ; z <= locs.maxZ; z++) {
|
|
||||||
final Faction fac = this.instance.getFactionAt(new FLocation(world.getName(), x, z));
|
|
||||||
if (fac == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// TODO types
|
|
||||||
if (!fac.getOnlinePlayers().contains(player)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (fac.isWilderness() && !perm) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package com.boydti.fawe.bukkit.regions;
|
|
||||||
|
|
||||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
|
||||||
import com.boydti.fawe.regions.FaweMask;
|
|
||||||
import com.sk89q.worldedit.BlockVector;
|
|
||||||
import java.util.List;
|
|
||||||
import net.sacredlabyrinth.Phaed.PreciousStones.PreciousStones;
|
|
||||||
import net.sacredlabyrinth.Phaed.PreciousStones.field.Field;
|
|
||||||
import net.sacredlabyrinth.Phaed.PreciousStones.field.FieldFlag;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
|
|
||||||
public class PreciousStonesFeature extends BukkitMaskManager implements Listener {
|
|
||||||
FaweBukkit plugin;
|
|
||||||
Plugin preciousstones;
|
|
||||||
|
|
||||||
public PreciousStonesFeature(final Plugin preciousstonesPlugin, final FaweBukkit p3) {
|
|
||||||
super(preciousstonesPlugin.getName());
|
|
||||||
this.preciousstones = preciousstonesPlugin;
|
|
||||||
this.plugin = p3;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAllowed(Player player, Field field, MaskType type, boolean allowMember) {
|
|
||||||
return field != null && (field.isOwner(player.getName()) || (type == MaskType.MEMBER && allowMember && field.getAllAllowed().contains(player.getName())));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FaweMask getMask(final FawePlayer<Player> fp, MaskType type) {
|
|
||||||
final Player player = fp.parent;
|
|
||||||
final Location location = player.getLocation();
|
|
||||||
final List<Field> fields = PreciousStones.API().getFieldsProtectingArea(FieldFlag.ALL, location);
|
|
||||||
if (fields.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String name = player.getName();
|
|
||||||
boolean member = fp.hasPermission("fawe.preciousstones.member");
|
|
||||||
for (final Field myField : fields) {
|
|
||||||
if (isAllowed(player, myField, type, member)) {
|
|
||||||
BlockVector pos1 = new BlockVector(myField.getMinx(), myField.getMiny(), myField.getMinz());
|
|
||||||
BlockVector pos2 = new BlockVector(myField.getMaxx(), myField.getMaxy(), myField.getMaxz());
|
|
||||||
return new FaweMask(pos1, pos2, "FIELD: " + myField) {
|
|
||||||
@Override
|
|
||||||
public boolean isValid(FawePlayer player, MaskType type) {
|
|
||||||
return isAllowed((Player) player.parent, myField, type, fp.hasPermission("fawe.preciousstones.member"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -158,7 +158,7 @@ public class BukkitQueue_1_12 extends BukkitQueue_0<net.minecraft.server.v1_12_R
|
|||||||
|
|
||||||
methodSaveChunk.invoke(cps, chunk, false);
|
methodSaveChunk.invoke(cps, chunk, false);
|
||||||
} else {
|
} else {
|
||||||
cps.saveChunk(chunk);
|
cps.saveChunk(chunk, false);
|
||||||
}
|
}
|
||||||
cps.saveChunkNOP(chunk);
|
cps.saveChunkNOP(chunk);
|
||||||
return true;
|
return true;
|
||||||
|
@ -130,7 +130,8 @@ public class BukkitQueue17 extends BukkitQueue_0<net.minecraft.server.v1_7_R4.Ch
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setMCA(final int mcaX, final int mcaZ, final RegionWrapper allowed, final Runnable whileLocked, boolean saveChunks, final boolean load) {
|
public boolean setMCA(final int mcaX, final int mcaZ, final RegionWrapper allowed, final Runnable whileLocked, boolean saveChunks, final boolean load) {
|
||||||
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
throw new UnsupportedOperationException();
|
||||||
|
/*TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Boolean value) {
|
public void run(Boolean value) {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
@ -239,7 +240,7 @@ public class BukkitQueue17 extends BukkitQueue_0<net.minecraft.server.v1_7_R4.Ch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -516,13 +517,12 @@ public class BukkitQueue17 extends BukkitQueue_0<net.minecraft.server.v1_7_R4.Ch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (EntityPlayer player : players) {
|
for (EntityPlayer player : players) {
|
||||||
int currentVersion = player.playerConnection.networkManager.getVersion();
|
|
||||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, 65280, currentVersion);
|
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, 65280);
|
||||||
player.playerConnection.sendPacket(packet);
|
player.playerConnection.sendPacket(packet);
|
||||||
mask = 255;
|
mask = 255;
|
||||||
}
|
}
|
||||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, mask, currentVersion);
|
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, mask);
|
||||||
player.playerConnection.sendPacket(packet);
|
player.playerConnection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
if (empty) {
|
if (empty) {
|
||||||
|
@ -32,6 +32,7 @@ import net.minecraft.server.v1_8_R3.Chunk;
|
|||||||
import net.minecraft.server.v1_8_R3.ChunkSection;
|
import net.minecraft.server.v1_8_R3.ChunkSection;
|
||||||
import net.minecraft.server.v1_8_R3.Entity;
|
import net.minecraft.server.v1_8_R3.Entity;
|
||||||
import net.minecraft.server.v1_8_R3.EntityPlayer;
|
import net.minecraft.server.v1_8_R3.EntityPlayer;
|
||||||
|
import net.minecraft.server.v1_8_R3.EntitySlice;
|
||||||
import net.minecraft.server.v1_8_R3.EntityTracker;
|
import net.minecraft.server.v1_8_R3.EntityTracker;
|
||||||
import net.minecraft.server.v1_8_R3.EntityTypes;
|
import net.minecraft.server.v1_8_R3.EntityTypes;
|
||||||
import net.minecraft.server.v1_8_R3.EnumDifficulty;
|
import net.minecraft.server.v1_8_R3.EnumDifficulty;
|
||||||
@ -130,7 +131,8 @@ public class BukkitQueue18R3 extends BukkitQueue_0<net.minecraft.server.v1_8_R3.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setMCA(final int mcaX, final int mcaZ, final RegionWrapper allowed, final Runnable whileLocked, final boolean saveChunks, final boolean load) {
|
public boolean setMCA(final int mcaX, final int mcaZ, final RegionWrapper allowed, final Runnable whileLocked, final boolean saveChunks, final boolean load) {
|
||||||
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
throw new UnsupportedOperationException();
|
||||||
|
/*TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Boolean value) {
|
public void run(Boolean value) {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
@ -239,7 +241,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<net.minecraft.server.v1_8_R3.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -534,7 +536,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<net.minecraft.server.v1_8_R3.
|
|||||||
|
|
||||||
public boolean hasEntities(net.minecraft.server.v1_8_R3.Chunk nmsChunk) {
|
public boolean hasEntities(net.minecraft.server.v1_8_R3.Chunk nmsChunk) {
|
||||||
for (int i = 0; i < nmsChunk.entitySlices.length; i++) {
|
for (int i = 0; i < nmsChunk.entitySlices.length; i++) {
|
||||||
List<Entity> slice = nmsChunk.entitySlices[i];
|
EntitySlice<Entity> slice = nmsChunk.entitySlices[i];
|
||||||
if (slice != null && !slice.isEmpty()) {
|
if (slice != null && !slice.isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
repositories {
|
repositories {
|
||||||
flatDir {dirs 'lib'}
|
flatDir {dirs 'lib'}
|
||||||
maven {url "http://ci.athion.net/job/PlotSquared-Legacy/ws/mvn/"}
|
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
compile 'org.yaml:snakeyaml:1.16'
|
compile 'org.yaml:snakeyaml:1.16'
|
||||||
compile 'com.google.code.gson:gson:2.2.4'
|
compile 'com.google.code.gson:gson:2.2.4'
|
||||||
compile 'net.fabiozumbi12:redprotect:1.9.6'
|
compile 'net.fabiozumbi12:redprotect:1.9.6'
|
||||||
compile group: "com.plotsquared", name: "plotsquared-api", version: "latest"
|
compile 'com.plotsquared:plotsquared-api:3.1'
|
||||||
compile 'org.primesoft:BlocksHub:2.0'
|
compile 'org.primesoft:BlocksHub:2.0'
|
||||||
compile 'com.github.luben:zstd-jni:1.1.1'
|
compile 'com.github.luben:zstd-jni:1.1.1'
|
||||||
// compile 'org.javassist:javassist:3.22.0-CR1'
|
// compile 'org.javassist:javassist:3.22.0-CR1'
|
||||||
@ -64,4 +63,4 @@ task copyFiles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
build.finalizedBy(copyFiles)
|
build.finalizedBy(copyFiles)
|
||||||
copyFiles.dependsOn(createPom)
|
copyFiles.dependsOn(createPom)
|
||||||
|
@ -68,6 +68,8 @@ public class Settings extends Config {
|
|||||||
@Create
|
@Create
|
||||||
public PATHS PATHS;
|
public PATHS PATHS;
|
||||||
@Create
|
@Create
|
||||||
|
public TAB_COMPLETION TAB_COMPLETION;
|
||||||
|
@Create
|
||||||
public REGION_RESTRICTIONS_OPTIONS REGION_RESTRICTIONS_OPTIONS;
|
public REGION_RESTRICTIONS_OPTIONS REGION_RESTRICTIONS_OPTIONS;
|
||||||
|
|
||||||
@Comment("Paths for various directories")
|
@Comment("Paths for various directories")
|
||||||
@ -165,6 +167,13 @@ public class Settings extends Config {
|
|||||||
public List<String> STRIP_NBT = new ArrayList<>();
|
public List<String> STRIP_NBT = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TAB_COMPLETION {
|
||||||
|
@Comment({"Entirely disabled tab completion to completely avoid exploits"})
|
||||||
|
public boolean ENABLED = true;
|
||||||
|
@Comment({"Max time tab-completes can attempt to operate for until being cancelled (ms)"})
|
||||||
|
public int MAX_TIME = 100;
|
||||||
|
}
|
||||||
|
|
||||||
public static class HISTORY {
|
public static class HISTORY {
|
||||||
@Comment({
|
@Comment({
|
||||||
"Should history be saved on disk:",
|
"Should history be saved on disk:",
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
package com.boydti.fawe.installer;
|
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.prefs.Preferences;
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.embed.swing.JFXPanel;
|
|
||||||
import javafx.stage.DirectoryChooser;
|
|
||||||
|
|
||||||
public abstract class BrowseButton extends InteractiveButton {
|
|
||||||
private final String id;
|
|
||||||
|
|
||||||
public BrowseButton(String id) {
|
|
||||||
super("Browse");
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void onSelect(File folder);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
Preferences prefs = Preferences.userRoot().node(Fawe.class.getName());
|
|
||||||
String lastUsed = prefs.get("LAST_USED_FOLDER", null);
|
|
||||||
final File lastFile = lastUsed == null ? null : new File(lastUsed).getParentFile();
|
|
||||||
browse(lastFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void browse(File from) {
|
|
||||||
DirectoryChooser folderChooser = new DirectoryChooser();
|
|
||||||
folderChooser.setInitialDirectory(from);
|
|
||||||
|
|
||||||
new JFXPanel(); // Init JFX Platform
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
File file = folderChooser.showDialog(null);
|
|
||||||
if (file != null && file.exists()) {
|
|
||||||
File parent = file.getParentFile();
|
|
||||||
if (parent == null) parent = file;
|
|
||||||
Preferences.userRoot().node(Fawe.class.getName()).put("LAST_USED_FOLDER" + id, parent.getPath());
|
|
||||||
onSelect(file);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package com.boydti.fawe.installer;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
|
|
||||||
public class CloseButton extends InteractiveButton {
|
|
||||||
public CloseButton() {
|
|
||||||
super("X");
|
|
||||||
setColor(new Color(0x66, 0x33, 0x33));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package com.boydti.fawe.installer;
|
|
||||||
|
|
||||||
|
|
||||||
import java.awt.AlphaComposite;
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.RenderingHints;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
|
|
||||||
public class ImagePanel extends JPanel {
|
|
||||||
|
|
||||||
private BufferedImage image;
|
|
||||||
|
|
||||||
public ImagePanel(BufferedImage image) {
|
|
||||||
this.image = image;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void paintComponent(Graphics g) {
|
|
||||||
Graphics2D g2d = (Graphics2D) g;
|
|
||||||
g2d.setRenderingHint(
|
|
||||||
RenderingHints.KEY_ANTIALIASING,
|
|
||||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
|
||||||
g2d.setComposite(AlphaComposite.getInstance(
|
|
||||||
AlphaComposite.SRC_OVER, 0.6f));
|
|
||||||
g.drawImage(image, 0, 0, getWidth(), getWidth(), this); // see javadoc for more info on the parameters
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,358 +0,0 @@
|
|||||||
package com.boydti.fawe.installer;
|
|
||||||
|
|
||||||
import com.boydti.fawe.FaweVersion;
|
|
||||||
import com.boydti.fawe.util.MainUtil;
|
|
||||||
import com.boydti.fawe.util.StringMan;
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.Container;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.FlowLayout;
|
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.nio.channels.Channels;
|
|
||||||
import java.nio.channels.ReadableByteChannel;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.JTextArea;
|
|
||||||
import javax.swing.SwingConstants;
|
|
||||||
import javax.swing.border.EmptyBorder;
|
|
||||||
|
|
||||||
public class InstallerFrame extends JFrame {
|
|
||||||
private final InvisiblePanel loggerPanel;
|
|
||||||
private Color LIGHT_GRAY = new Color(0x66, 0x66, 0x66);
|
|
||||||
private Color GRAY = new Color(0x44, 0x44, 0x46);
|
|
||||||
private Color DARK_GRAY = new Color(0x33, 0x33, 0x36);
|
|
||||||
private Color DARKER_GRAY = new Color(0x26, 0x26, 0x28);
|
|
||||||
private Color INVISIBLE = new Color(0, 0, 0, 0);
|
|
||||||
private Color OFF_WHITE = new Color(200, 200, 200);
|
|
||||||
|
|
||||||
private JTextArea loggerTextArea;
|
|
||||||
private BrowseButton browse;
|
|
||||||
|
|
||||||
public InstallerFrame() throws Exception {
|
|
||||||
final MovablePanel movable = new MovablePanel(this);
|
|
||||||
|
|
||||||
Container content = this.getContentPane();
|
|
||||||
content.add(movable);
|
|
||||||
this.setSize(480, 320);
|
|
||||||
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
this.setUndecorated(true);
|
|
||||||
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
|
|
||||||
int x = (int) ((dimension.getWidth() - this.getWidth()) / 2);
|
|
||||||
int y = (int) ((dimension.getHeight() - this.getHeight()) / 2);
|
|
||||||
this.setLocation(x, y);
|
|
||||||
this.setVisible(true);
|
|
||||||
this.setOpacity(0);
|
|
||||||
movable.setBackground(DARK_GRAY);
|
|
||||||
movable.setLayout(new BorderLayout());
|
|
||||||
|
|
||||||
fadeIn();
|
|
||||||
|
|
||||||
JPanel topBar = new InvisiblePanel(new BorderLayout());
|
|
||||||
{
|
|
||||||
JPanel topBarLeft = new InvisiblePanel();
|
|
||||||
JPanel topBarRight = new InvisiblePanel();
|
|
||||||
|
|
||||||
JLabel title = new JLabel("FastAsyncWorldEdit Installer");
|
|
||||||
title.setHorizontalAlignment(SwingConstants.CENTER);
|
|
||||||
title.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
|
||||||
title.setForeground(LIGHT_GRAY);
|
|
||||||
|
|
||||||
MinimizeButton minimize = new MinimizeButton(this);
|
|
||||||
CloseButton exit = new CloseButton();
|
|
||||||
|
|
||||||
topBarLeft.add(title);
|
|
||||||
topBarRight.add(minimize);
|
|
||||||
topBarRight.add(exit);
|
|
||||||
|
|
||||||
topBar.add(topBarLeft, BorderLayout.CENTER);
|
|
||||||
topBar.add(topBarRight, BorderLayout.EAST);
|
|
||||||
}
|
|
||||||
final JPanel mainContent = new InvisiblePanel(new BorderLayout());
|
|
||||||
{
|
|
||||||
final JPanel browseContent = new InvisiblePanel(new BorderLayout());
|
|
||||||
File dir = MainUtil.getWorkingDirectory("minecraft");
|
|
||||||
JLabel folder = new JLabel("Folder: ");
|
|
||||||
folder.setForeground(OFF_WHITE);
|
|
||||||
final InteractiveButton text = new InteractiveButton(dir.getPath(), DARKER_GRAY) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
browse.actionPerformed(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
text.setForeground(OFF_WHITE);
|
|
||||||
text.setBackground(DARKER_GRAY);
|
|
||||||
text.setOpaque(true);
|
|
||||||
text.setBorder(new EmptyBorder(4, 4, 4, 4));
|
|
||||||
browse = new BrowseButton("") {
|
|
||||||
@Override
|
|
||||||
public void onSelect(File folder) {
|
|
||||||
text.setText(folder.getPath());
|
|
||||||
movable.repaint();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
InteractiveButton install = new InteractiveButton(">> Create Profile <<", DARKER_GRAY) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
try {
|
|
||||||
install(text.getText());
|
|
||||||
} catch (Exception e1) {
|
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
browseContent.add(folder, BorderLayout.WEST);
|
|
||||||
browseContent.add(text, BorderLayout.CENTER);
|
|
||||||
browseContent.add(browse, BorderLayout.EAST);
|
|
||||||
final JPanel installContent = new InvisiblePanel(new FlowLayout());
|
|
||||||
install.setPreferredSize(new Dimension(416, 32));
|
|
||||||
installContent.add(install);
|
|
||||||
installContent.setBorder(new EmptyBorder(10, 0, 10, 0));
|
|
||||||
this.loggerPanel = new InvisiblePanel(new BorderLayout());
|
|
||||||
this.loggerPanel.setBackground(Color.GREEN);
|
|
||||||
loggerPanel.setPreferredSize(new Dimension(416, 160));
|
|
||||||
loggerTextArea = new JTextArea(12, 52);
|
|
||||||
loggerTextArea.setBackground(GRAY);
|
|
||||||
loggerTextArea.setForeground(DARKER_GRAY);
|
|
||||||
loggerTextArea.setFont(new Font(loggerTextArea.getFont().getName(), Font.PLAIN, 9));
|
|
||||||
JScrollPane scroll = new JScrollPane(loggerTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
|
||||||
scroll.setBackground(DARK_GRAY);
|
|
||||||
scroll.setBorder(new EmptyBorder(0, 0, 0, 0));
|
|
||||||
loggerPanel.add(scroll);
|
|
||||||
loggerPanel.setVisible(false);
|
|
||||||
|
|
||||||
mainContent.setBorder(new EmptyBorder(6, 32, 6, 32));
|
|
||||||
mainContent.add(browseContent, BorderLayout.NORTH);
|
|
||||||
mainContent.add(installContent, BorderLayout.CENTER);
|
|
||||||
mainContent.add(loggerPanel, BorderLayout.SOUTH);
|
|
||||||
}
|
|
||||||
JPanel bottomBar = new InvisiblePanel();
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
InputStream stream = getClass().getResourceAsStream("/fawe.properties");
|
|
||||||
java.util.Scanner scanner = new java.util.Scanner(stream).useDelimiter("\\A");
|
|
||||||
String versionString = scanner.next().trim();
|
|
||||||
scanner.close();
|
|
||||||
FaweVersion version = new FaweVersion(versionString);
|
|
||||||
String date = new Date(100 + version.year, version.month, version.day).toGMTString();
|
|
||||||
String build = "https://ci.athion.net/job/FastAsyncWorldEdit/" + version.build;
|
|
||||||
String commit = "https://github.com/boy0001/FastAsyncWorldedit/commit/" + Integer.toHexString(version.hash);
|
|
||||||
String footerMessage = "FAWE v" + version.major + "." + version.minor + "." + version.patch + " by Empire92 (c) 2017 (GPL v3.0)";
|
|
||||||
URL licenseUrl = new URL("https://github.com/boy0001/FastAsyncWorldedit/blob/master/LICENSE");
|
|
||||||
URLButton licenseButton = new URLButton(licenseUrl, footerMessage);
|
|
||||||
bottomBar.add(licenseButton);
|
|
||||||
} catch (Throwable ignore) {
|
|
||||||
ignore.printStackTrace();
|
|
||||||
}
|
|
||||||
URL chat = new URL("https://discord.gg/ngZCzbU");
|
|
||||||
URLButton chatButton = new URLButton(chat, "Chat");
|
|
||||||
bottomBar.add(chatButton);
|
|
||||||
URL wiki = new URL("https://github.com/boy0001/FastAsyncWorldedit/wiki");
|
|
||||||
URLButton wikiButton = new URLButton(wiki, "Wiki");
|
|
||||||
bottomBar.add(wikiButton);
|
|
||||||
URL issue = new URL("https://github.com/boy0001/FastAsyncWorldedit/issues/new");
|
|
||||||
URLButton issueButton = new URLButton(issue, "Report Issue");
|
|
||||||
bottomBar.add(issueButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We want to add these a bit later
|
|
||||||
movable.add(topBar, BorderLayout.NORTH);
|
|
||||||
this.setVisible(true);
|
|
||||||
this.repaint();
|
|
||||||
movable.add(mainContent, BorderLayout.CENTER);
|
|
||||||
this.setVisible(true);
|
|
||||||
this.repaint();
|
|
||||||
movable.add(bottomBar, BorderLayout.SOUTH);
|
|
||||||
this.setVisible(true);
|
|
||||||
this.repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean newLine = false;
|
|
||||||
|
|
||||||
public void prompt(String message) {
|
|
||||||
JOptionPane.showMessageDialog(null, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void debug(String m) {
|
|
||||||
System.out.println(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void install(String name) throws Exception {
|
|
||||||
if (!loggerPanel.isVisible()) {
|
|
||||||
loggerPanel.setVisible(true);
|
|
||||||
this.repaint();
|
|
||||||
System.setOut(new TextAreaOutputStream(loggerTextArea));
|
|
||||||
}
|
|
||||||
if (name == null || name.isEmpty()) {
|
|
||||||
prompt("No folder selection");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final File dirMc = new File(name);
|
|
||||||
if (!dirMc.exists()) {
|
|
||||||
prompt("Folder does not exist");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!dirMc.isDirectory()) {
|
|
||||||
prompt("You must select a folder, not a file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Thread installThread = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
List<String> supported = Arrays.asList("v1710", "v189", "v194", "v110", "v111");
|
|
||||||
String supportedString = null;
|
|
||||||
for (String version : supported) {
|
|
||||||
try {
|
|
||||||
Class.forName("com.boydti.fawe.forge." + version + ".ForgeChunk_All");
|
|
||||||
supportedString = version;
|
|
||||||
break;
|
|
||||||
} catch (ClassNotFoundException ignore) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (supportedString == null) {
|
|
||||||
prompt("This version of FAWE cannot be installed this way.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
debug("Selected version " + supportedString);
|
|
||||||
URL forgeUrl;
|
|
||||||
URL worldEditUrl;
|
|
||||||
URL worldEditCuiUrl;
|
|
||||||
try {
|
|
||||||
switch (supportedString) {
|
|
||||||
case "v111":
|
|
||||||
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.11.2-13.20.0.2201/forge-1.11.2-13.20.0.2201-installer.jar");
|
|
||||||
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9593/download/worldedit-forge-mc1.11-6.1.6-SNAPSHOT-dist.jar");
|
|
||||||
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/241/worldeditcuife-v1.0.6-mf-1.11.2-13.20.0.2201.jar");
|
|
||||||
break;
|
|
||||||
case "v110":
|
|
||||||
forgeUrl = new URL("http://files.minecraftforge.net/maven/net/minecraftforge/forge/1.10.2-12.18.3.2185/forge-1.10.2-12.18.3.2185-installer.jar");
|
|
||||||
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9395/download/worldedit-forge-mc1.10.2-6.1.4-SNAPSHOT-dist.jar");
|
|
||||||
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/239/WorldEditCuiFe-v1.0.6-mf-1.10.2-12.18.2.2125.jar");
|
|
||||||
break;
|
|
||||||
case "v194":
|
|
||||||
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.9.4-12.17.0.2051/forge-1.9.4-12.17.0.2051-installer.jar");
|
|
||||||
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9171/download/worldedit-forge-mc1.9.4-6.1.3-SNAPSHOT-dist.jar");
|
|
||||||
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/236/WorldEditCuiFe-v1.0.6-mf-1.9.4-12.17.0.1976.jar");
|
|
||||||
break;
|
|
||||||
case "v189":
|
|
||||||
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.8.9-11.15.1.1902-1.8.9/forge-1.8.9-11.15.1.1902-1.8.9-installer.jar");
|
|
||||||
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/8755/download/worldedit-forge-mc1.8.9-6.1.1-dist.jar");
|
|
||||||
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/235/WorldEditCuiFe-v1.0.6-mf-1.8.9-11.15.1.1855.jar");
|
|
||||||
break;
|
|
||||||
case "v1710":
|
|
||||||
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.7.10-10.13.4.1614-1.7.10/forge-1.7.10-10.13.4.1614-1.7.10-installer.jar");
|
|
||||||
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9194/download/worldedit-forge-mc1.7.10-6.1.2-SNAPSHOT-dist.jar");
|
|
||||||
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/234/WorldEditCuiFe-v1.0.6-mf-1.7.10-10.13.4.1566.jar");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try { // install forge
|
|
||||||
debug("Downloading forge installer from:\n - https://files.minecraftforge.net/");
|
|
||||||
URLClassLoader loader = new URLClassLoader(new URL[]{forgeUrl});
|
|
||||||
debug("Connected");
|
|
||||||
Class<?> forgeInstallClass = loader.loadClass("net.minecraftforge.installer.ClientInstall");
|
|
||||||
debug("Found ClientInstall class");
|
|
||||||
Object forgeInstallInstance = forgeInstallClass.newInstance();
|
|
||||||
debug(forgeInstallInstance + " | " + forgeInstallClass + " | " + StringMan.getString(forgeInstallClass.getMethods()));
|
|
||||||
debug("Created instance " + forgeInstallInstance);
|
|
||||||
Method methodRun = forgeInstallClass.getDeclaredMethods()[0];//("run", File.class, Predicate.class);
|
|
||||||
Object alwaysTrue = loader.loadClass("com.google.common.base.Predicates").getDeclaredMethod("alwaysTrue").invoke(null);
|
|
||||||
methodRun.invoke(forgeInstallInstance, dirMc, alwaysTrue);
|
|
||||||
debug("Forge profile created, now installing WorldEdit");
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
prompt("[ERROR] Forge install failed, download from:\nhttps://files.minecraftforge.net/");
|
|
||||||
}
|
|
||||||
File mods = new File(dirMc, "mods");
|
|
||||||
if (!mods.exists()) {
|
|
||||||
debug("Creating mods directory");
|
|
||||||
mods.mkdirs();
|
|
||||||
} else {
|
|
||||||
for (File file : mods.listFiles()) {
|
|
||||||
String name = file.getName().toLowerCase();
|
|
||||||
if ((name.contains("worldedit") || name.contains("fawe"))) {
|
|
||||||
debug("Delete existing: " + file.getName());
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try { // install worldedit
|
|
||||||
debug("Downloading WE-CUI from:\n - https://minecraft.curseforge.com/projects/worldeditcui-forge-edition");
|
|
||||||
try (ReadableByteChannel rbc = Channels.newChannel(worldEditCuiUrl.openStream())) {
|
|
||||||
try (FileOutputStream fos = new FileOutputStream(new File(mods, "WorldEditCUI.jar"))) {
|
|
||||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug("Successfully downloaded WorldEdit-CUI");
|
|
||||||
} catch (Throwable e) {
|
|
||||||
prompt("[ERROR] WorldEdit install failed, download from:\nhttp://builds.enginehub.org/job/worldedit");
|
|
||||||
}
|
|
||||||
try { // install worldedit
|
|
||||||
debug("Downloading WorldEdit from:\n - http://builds.enginehub.org/job/worldedit");
|
|
||||||
try (ReadableByteChannel rbc = Channels.newChannel(worldEditUrl.openStream())) {
|
|
||||||
try (FileOutputStream fos = new FileOutputStream(new File(mods, "WorldEdit.jar"))) {
|
|
||||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug("Successfully downloaded WorldEdit");
|
|
||||||
} catch (Throwable e) {
|
|
||||||
prompt("[ERROR] WorldEdit install failed, download from:\nhttp://builds.enginehub.org/job/worldedit");
|
|
||||||
}
|
|
||||||
try { // install FAWE
|
|
||||||
debug("Copying FastAsyncWorldEdit to mods directory");
|
|
||||||
File file = new File(InstallerFrame.class.getProtectionDomain().getCodeSource().getLocation().getPath());
|
|
||||||
debug(" - " + file.getPath());
|
|
||||||
MainUtil.copyFile(file, new File(mods, "FastAsyncWorldEdit.jar"));
|
|
||||||
debug("Installation complete!");
|
|
||||||
} catch (Throwable e) {
|
|
||||||
prompt("[ERROR] Copy installer failed, please copy this installer jar manually");
|
|
||||||
}
|
|
||||||
prompt("Installation complete!\nLaunch the game using the forge profile.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
installThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fadeIn() {
|
|
||||||
Thread thread = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
for (float i = 0; i <= 1; i += 0.001) {
|
|
||||||
InstallerFrame.this.setOpacity(i);
|
|
||||||
try {
|
|
||||||
Thread.sleep(1);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
InstallerFrame window = new InstallerFrame();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
package com.boydti.fawe.installer;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.awt.event.MouseListener;
|
|
||||||
import javax.swing.JButton;
|
|
||||||
|
|
||||||
public class InteractiveButton extends JButton implements ActionListener, MouseListener {
|
|
||||||
private Color background;
|
|
||||||
|
|
||||||
public InteractiveButton(String text) {
|
|
||||||
this(text, new Color(0, 0, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
public InteractiveButton(String text, Color background) {
|
|
||||||
setText(text);
|
|
||||||
setBorderPainted(false);
|
|
||||||
setVisible(true);
|
|
||||||
setForeground(new Color(200, 200, 200));
|
|
||||||
addActionListener(this);
|
|
||||||
addMouseListener(this);
|
|
||||||
setFocusable(false);
|
|
||||||
if (background.getAlpha() != 0) {
|
|
||||||
this.background = background;
|
|
||||||
} else {
|
|
||||||
this.background = new Color(0x38, 0x38, 0x39);
|
|
||||||
}
|
|
||||||
setBackground(this.background);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColor(Color background) {
|
|
||||||
setBackground(background);
|
|
||||||
this.background = background;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(MouseEvent e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseEntered(MouseEvent e) {
|
|
||||||
setBackground(new Color(0x44, 0x44, 0x44));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseExited(MouseEvent e) {
|
|
||||||
setBackground(this.background);
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mousePressed(MouseEvent e) {
|
|
||||||
setBackground(new Color(0x77, 0x77, 0x77));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(MouseEvent e) {
|
|
||||||
setBackground(new Color(0x33, 0x33, 0x36));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
package com.boydti.fawe.installer;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.FlowLayout;
|
|
||||||
import java.awt.LayoutManager;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
|
|
||||||
public class InvisiblePanel extends JPanel {
|
|
||||||
public InvisiblePanel(LayoutManager layout) {
|
|
||||||
super(layout);
|
|
||||||
setBackground(new Color(0, 0, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvisiblePanel() {
|
|
||||||
this(new FlowLayout());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
package com.boydti.fawe.installer;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.Container;
|
|
||||||
import javax.swing.JFileChooser;
|
|
||||||
import javax.swing.LookAndFeel;
|
|
||||||
import javax.swing.UIManager;
|
|
||||||
import javax.swing.UnsupportedLookAndFeelException;
|
|
||||||
import sun.swing.FilePane;
|
|
||||||
|
|
||||||
public class JSystemFileChooser extends JFileChooser {
|
|
||||||
public void updateUI(){
|
|
||||||
LookAndFeel old = UIManager.getLookAndFeel();
|
|
||||||
try {
|
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
||||||
}
|
|
||||||
catch (Throwable ex) {
|
|
||||||
old = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateUI();
|
|
||||||
|
|
||||||
if(old != null){
|
|
||||||
FilePane filePane = findFilePane(this);
|
|
||||||
filePane.setViewType(FilePane.VIEWTYPE_DETAILS);
|
|
||||||
filePane.setViewType(FilePane.VIEWTYPE_LIST);
|
|
||||||
|
|
||||||
Color background = UIManager.getColor("Label.background");
|
|
||||||
setBackground(background);
|
|
||||||
setOpaque(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
UIManager.setLookAndFeel(old);
|
|
||||||
}
|
|
||||||
catch (UnsupportedLookAndFeelException ignored) {} // shouldn't get here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static FilePane findFilePane(Container parent){
|
|
||||||
for(Component comp: parent.getComponents()){
|
|
||||||
if(FilePane.class.isInstance(comp)){
|
|
||||||
return (FilePane)comp;
|
|
||||||
}
|
|
||||||
if(comp instanceof Container){
|
|
||||||
Container cont = (Container)comp;
|
|
||||||
if(cont.getComponentCount() > 0){
|
|
||||||
FilePane found = findFilePane(cont);
|
|
||||||
if (found != null) {
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package com.boydti.fawe.installer;
|
|
||||||
|
|
||||||
import java.awt.Frame;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
|
|
||||||
public class MinimizeButton extends InteractiveButton {
|
|
||||||
private final JFrame window;
|
|
||||||
|
|
||||||
public MinimizeButton(JFrame window) {
|
|
||||||
super("-");
|
|
||||||
this.window = window;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
window.setState(Frame.ICONIFIED);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package com.boydti.fawe.installer;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.awt.event.MouseMotionAdapter;
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
|
|
||||||
public class MovablePanel extends JPanel {
|
|
||||||
private Point initialClick;
|
|
||||||
private JFrame parent;
|
|
||||||
|
|
||||||
public MovablePanel(final JFrame parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
|
|
||||||
addMouseListener(new MouseAdapter() {
|
|
||||||
public void mousePressed(MouseEvent e) {
|
|
||||||
initialClick = e.getPoint();
|
|
||||||
getComponentAt(initialClick);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addMouseMotionListener(new MouseMotionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void mouseDragged(MouseEvent e) {
|
|
||||||
|
|
||||||
// get location of Window
|
|
||||||
int thisX = parent.getLocation().x;
|
|
||||||
int thisY = parent.getLocation().y;
|
|
||||||
|
|
||||||
// Determine how much the mouse moved since the initial click
|
|
||||||
int xMoved = (thisX + e.getX()) - (thisX + initialClick.x);
|
|
||||||
int yMoved = (thisY + e.getY()) - (thisY + initialClick.y);
|
|
||||||
|
|
||||||
// Move window to this position
|
|
||||||
int X = thisX + xMoved;
|
|
||||||
int Y = thisY + yMoved;
|
|
||||||
parent.setLocation(X, Y);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
package com.boydti.fawe.installer;
|
|
||||||
|
|
||||||
import com.boydti.fawe.config.BBC;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import javax.swing.JTextArea;
|
|
||||||
|
|
||||||
public class TextAreaOutputStream extends PrintStream {
|
|
||||||
|
|
||||||
public TextAreaOutputStream(final JTextArea textArea) {
|
|
||||||
super(new OutputStream() {
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
|
||||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
|
||||||
AtomicBoolean updated = new AtomicBoolean();
|
|
||||||
AtomicBoolean waiting = new AtomicBoolean();
|
|
||||||
boolean lineColor = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(int b) throws IOException {
|
|
||||||
buffer.append((char) b);
|
|
||||||
if (b == '\n') {
|
|
||||||
updated.set(true);
|
|
||||||
if (waiting.compareAndSet(false, true)) {
|
|
||||||
executor.submit(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
updated.set(false);
|
|
||||||
int len = buffer.length();
|
|
||||||
textArea.append(BBC.stripColor(buffer.substring(0, len)));
|
|
||||||
buffer.delete(0, len);
|
|
||||||
textArea.setVisible(true);
|
|
||||||
textArea.repaint();
|
|
||||||
} finally {
|
|
||||||
waiting.set(false);
|
|
||||||
if (updated.get() && waiting.compareAndSet(false, true)) {
|
|
||||||
executor.submit(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updated.lazySet(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void finalize() throws Throwable {
|
|
||||||
executor.shutdownNow();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package com.boydti.fawe.installer;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Desktop;
|
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.datatransfer.Clipboard;
|
|
||||||
import java.awt.datatransfer.StringSelection;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
public class URLButton extends InteractiveButton {
|
|
||||||
private final URL url;
|
|
||||||
|
|
||||||
public URLButton(URL url, String text) {
|
|
||||||
super("<HTML>" + text + "</HTML>");
|
|
||||||
this.url = url;
|
|
||||||
setFont(new Font(getFont().getName(), Font.PLAIN, 9));
|
|
||||||
setForeground(new Color(0x77, 0x77, 0x77));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent event) {
|
|
||||||
if (Desktop.isDesktopSupported()) {
|
|
||||||
try {
|
|
||||||
Desktop.getDesktop().browse(url.toURI());
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
|
|
||||||
Clipboard systemClipboard = defaultToolkit.getSystemClipboard();
|
|
||||||
systemClipboard.setContents(new StringSelection(url.toString()), null);
|
|
||||||
}
|
|
||||||
}
|
|
@ -25,6 +25,7 @@ import com.boydti.fawe.command.CFICommand;
|
|||||||
import com.boydti.fawe.command.MaskBinding;
|
import com.boydti.fawe.command.MaskBinding;
|
||||||
import com.boydti.fawe.command.PatternBinding;
|
import com.boydti.fawe.command.PatternBinding;
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.exception.FaweException;
|
import com.boydti.fawe.object.exception.FaweException;
|
||||||
import com.boydti.fawe.object.task.ThrowableSupplier;
|
import com.boydti.fawe.object.task.ThrowableSupplier;
|
||||||
@ -69,6 +70,12 @@ import java.util.LinkedHashSet;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.logging.FileHandler;
|
import java.util.logging.FileHandler;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -144,6 +151,7 @@ public final class CommandManager {
|
|||||||
} catch (ClassNotFoundException e) {}
|
} catch (ClassNotFoundException e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
/**
|
||||||
* Register all the methods in the class as commands<br>
|
* Register all the methods in the class as commands<br>
|
||||||
* - You should try to register commands during startup
|
* - You should try to register commands during startup
|
||||||
@ -544,12 +552,29 @@ public final class CommandManager {
|
|||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void handleCommandSuggestion(CommandSuggestionEvent event) {
|
public void handleCommandSuggestion(CommandSuggestionEvent event) {
|
||||||
try {
|
if (!Settings.IMP.TAB_COMPLETION.ENABLED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||||
|
//Do not let tab completions hang the main thread for more than 5 seconds.
|
||||||
|
Future<Object> future = executorService.submit(() -> {
|
||||||
CommandLocals locals = new CommandLocals();
|
CommandLocals locals = new CommandLocals();
|
||||||
locals.put(Actor.class, event.getActor());
|
locals.put(Actor.class, event.getActor());
|
||||||
event.setSuggestions(dispatcher.getSuggestions(event.getArguments(), locals));
|
try {
|
||||||
} catch (CommandException e) {
|
event.setSuggestions(dispatcher.getSuggestions(event.getArguments(), locals));
|
||||||
event.getActor().printError(e.getMessage());
|
} catch (CommandException e) {
|
||||||
|
event.getActor().printError(e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
future.get(Settings.IMP.TAB_COMPLETION.MAX_TIME, TimeUnit.MILLISECONDS);
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
event.getActor().printError(e.getCause().getMessage());
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
event.getActor().printError("Tab complete took too long.");
|
||||||
|
} finally {
|
||||||
|
executorService.shutdownNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,4 +595,4 @@ public final class CommandManager {
|
|||||||
public static Class<CommandManager> inject() {
|
public static Class<CommandManager> inject() {
|
||||||
return CommandManager.class;
|
return CommandManager.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
rootProject.name = 'FastAsyncWorldEdit'
|
rootProject.name = 'FastAsyncWorldEdit'
|
||||||
|
|
||||||
include 'core', 'bukkit', 'favs', 'nukkit', 'forge189', 'forge194', 'forge110', 'forge111', 'forge112', 'sponge111', 'sponge112' // 'forge1710'
|
include 'core', 'bukkit', 'favs'//, 'nukkit', 'forge189', 'forge194', 'forge110', 'forge111', 'forge112', 'sponge111', 'sponge112'//, 'forge1710'
|
||||||
|
Loading…
Reference in New Issue
Block a user