Multi-port supports w/ Removes tickable of enchant table

This commit is contained in:
Sotr
2018-05-30 00:58:55 +08:00
parent 6f98d609a9
commit 0425dbce8f
6 changed files with 185 additions and 8 deletions

View File

@@ -0,0 +1,151 @@
package io.akarin.server.core;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import io.akarin.api.LogWrapper;
public class AkarinGlobalConfig {
private static File CONFIG_FILE;
private static final String HEADER = "This is the global configuration file for Akarin.\n"
+ "Some options may impact gameplay, so use with caution,\n"
+ "and make sure you know what each option does before configuring.\n"
+ "\n"
+ "Akarin forums: https://akarin.io/ \n";
/*========================================================================*/
public static YamlConfiguration config;
static int version;
/*========================================================================*/
public static void init(File configFile) {
CONFIG_FILE = configFile;
config = new YamlConfiguration();
try {
config.load(CONFIG_FILE);
} catch (IOException ex) {
} catch (InvalidConfigurationException ex) {
LogWrapper.logger.error("Could not load akarin.yml, please correct your syntax errors", ex);
throw Throwables.propagate(ex);
}
config.options().header(HEADER);
config.options().copyDefaults(true);
version = getInt("config-version", 1);
set("config-version", 1);
readConfig(AkarinGlobalConfig.class, null);
}
static void readConfig(Class<?> clazz, Object instance) {
for (Method method : clazz.getDeclaredMethods()) {
if (Modifier.isPrivate(method.getModifiers())) {
if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) {
try {
method.setAccessible(true);
method.invoke(instance);
} catch (InvocationTargetException ex) {
throw Throwables.propagate(ex.getCause());
} catch (Exception ex) {
LogWrapper.logger.error("Error invoking " + method, ex);
}
}
}
}
try {
config.save(CONFIG_FILE);
} catch (IOException ex) {
LogWrapper.logger.error("Could not save " + CONFIG_FILE, ex);
}
}
private static final Pattern SPACE = Pattern.compile(" ");
private static final Pattern NOT_NUMERIC = Pattern.compile("[^-\\d.]");
public static int getSeconds(String str) {
str = SPACE.matcher(str).replaceAll("");
final char unit = str.charAt(str.length() - 1);
str = NOT_NUMERIC.matcher(str).replaceAll("");
double num;
try {
num = Double.parseDouble(str);
} catch (Exception e) {
num = 0D;
}
switch (unit) {
case 'd': num *= (double) 60*60*24; break;
case 'h': num *= (double) 60*60; break;
case 'm': num *= 60; break;
default: case 's': break;
}
return (int) num;
}
protected static String timeSummary(int seconds) {
String time = "";
if (seconds > 60 * 60 * 24) {
time += TimeUnit.SECONDS.toDays(seconds) + "d";
seconds %= 60 * 60 * 24;
}
if (seconds > 60 * 60) {
time += TimeUnit.SECONDS.toHours(seconds) + "h";
seconds %= 60 * 60;
}
if (seconds > 0) {
time += TimeUnit.SECONDS.toMinutes(seconds) + "m";
}
return time;
}
private static void set(String path, Object val) {
config.set(path, val);
}
private static boolean getBoolean(String path, boolean def) {
config.addDefault(path, def);
return config.getBoolean(path, config.getBoolean(path));
}
private static double getDouble(String path, double def) {
config.addDefault(path, def);
return config.getDouble(path, config.getDouble(path));
}
private static float getFloat(String path, float def) {
// TODO: Figure out why getFloat() always returns the default value.
return (float) getDouble(path, def);
}
private static int getInt(String path, int def) {
config.addDefault(path, def);
return config.getInt(path, config.getInt(path));
}
private static <T> List getList(String path, T def) {
config.addDefault(path, def);
return config.getList(path, config.getList(path));
}
private static String getString(String path, String def) {
config.addDefault(path, def);
return config.getString(path, config.getString(path));
}
/*========================================================================*/
public static List<String> extraAddress;
private static void extraAddress() {
extraAddress = getList("network.extra-local-address", Lists.newArrayList());
}
}

View File

@@ -1,5 +1,6 @@
package io.akarin.server.mixin.core; package io.akarin.server.mixin.core;
import java.io.File;
import java.io.PrintStream; import java.io.PrintStream;
import org.bukkit.craftbukkit.Main; import org.bukkit.craftbukkit.Main;
@@ -10,12 +11,13 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import io.akarin.api.LogWrapper; import io.akarin.api.LogWrapper;
import io.akarin.server.core.AkarinGlobalConfig;
@Mixin(value = Main.class, remap = false) @Mixin(value = Main.class, remap = false)
public class Bootstrap { public class Bootstrap {
@Inject(method = "main([Ljava/lang/String;)V", at = @At("HEAD")) @Inject(method = "main([Ljava/lang/String;)V", at = @At("HEAD"))
private static void configureMixin(CallbackInfo info) { private static void premain(CallbackInfo info) {
; AkarinGlobalConfig.init(new File("akarin.yml"));
} }
/* /*

View File

@@ -0,0 +1,11 @@
package io.akarin.server.mixin.core;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import net.minecraft.server.TileEntityEnchantTable;
@Mixin(value = TileEntityEnchantTable.class, remap = false)
public class MixinTileEntityEnchantTable {
@Overwrite
public void e() {} // No tickable
}

View File

@@ -46,7 +46,7 @@ public class MixinVersionCommand {
private volatile boolean versionObtaining; private volatile boolean versionObtaining;
private long lastCheckMillis; private long lastCheckMillis;
private CommandSender currentSender; private CommandSender currentSender;
private boolean customVersion; private boolean customVersion;
// The name can lead to misunderstand, // The name can lead to misunderstand,
@@ -122,7 +122,7 @@ public class MixinVersionCommand {
break; break;
case -2: case -2:
setVersionMessage("Unknown version"); setVersionMessage("Unknown version");
customVersion = true; customVersion = true;
break; break;
default: default:
setVersionMessage("You are " + distance + " version(s) behind"); setVersionMessage("You are " + distance + " version(s) behind");

View File

@@ -2,6 +2,7 @@ package io.akarin.server.mixin.core;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -20,6 +21,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import io.akarin.api.LocalAddress; import io.akarin.api.LocalAddress;
import io.akarin.api.WrappedCollections; import io.akarin.api.WrappedCollections;
import io.akarin.server.core.AkarinGlobalConfig;
import io.akarin.server.core.ChannelAdapter; import io.akarin.server.core.ChannelAdapter;
import io.netty.bootstrap.ServerBootstrap; import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
@@ -76,7 +78,7 @@ public class NonblockingServerConnection {
*/ */
@Overwrite @Overwrite
public void a(InetAddress address, int port) throws IOException { public void a(InetAddress address, int port) throws IOException {
registerChannels(Collections.singleton(LocalAddress.create(address, port))); registerChannels(Lists.newArrayList(LocalAddress.create(address, port)));
} }
public void registerChannels(Collection<LocalAddress> data) throws IOException { public void registerChannels(Collection<LocalAddress> data) throws IOException {
@@ -95,6 +97,16 @@ public class NonblockingServerConnection {
ServerBootstrap bootstrap = new ServerBootstrap().channel(channelClass).childHandler(ChannelAdapter.create(h)).group(loopGroup); ServerBootstrap bootstrap = new ServerBootstrap().channel(channelClass).childHandler(ChannelAdapter.create(h)).group(loopGroup);
synchronized (g) { synchronized (g) {
data.addAll(Lists.transform(AkarinGlobalConfig.extraAddress, s -> {
String[] info = s.split(":");
try {
logger.info("Attempt to bind server on " + s);
return LocalAddress.create(InetAddress.getByName(info[0]), Integer.valueOf(info[1]));
} catch (NumberFormatException | UnknownHostException ex) {
logger.error("Error on lookup additional host, wrong format?", ex);
return null;
}
}));
data.forEach(address -> g.add(bootstrap.localAddress(address.host(), address.port()).bind().syncUninterruptibly())); // supports multi-port bind data.forEach(address -> g.add(bootstrap.localAddress(address.host(), address.port()).bind().syncUninterruptibly())); // supports multi-port bind
} }
} }
@@ -106,7 +118,7 @@ public class NonblockingServerConnection {
public void b() { public void b() {
this.d = false; this.d = false;
try { try {
synchronized (g) { synchronized (g) { // safe fixes
for (ChannelFuture channel : g) channel.channel().close().sync(); for (ChannelFuture channel : g) channel.channel().close().sync();
} }
} catch (InterruptedException ex) { } catch (InterruptedException ex) {

View File

@@ -15,6 +15,7 @@
"MixinPaperConfig", "MixinPaperConfig",
"MixinCraftServer", "MixinCraftServer",
"MixinVersionCommand", "MixinVersionCommand",
"MixinMinecraftServer" "MixinMinecraftServer",
"MixinTileEntityEnchantTable"
] ]
} }