parent
24b67df9a2
commit
eb2887bb46
|
@ -6,6 +6,7 @@
|
||||||
*.iws
|
*.iws
|
||||||
.idea
|
.idea
|
||||||
out
|
out
|
||||||
|
build
|
||||||
|
|
||||||
#eclipse
|
#eclipse
|
||||||
.project
|
.project
|
||||||
|
@ -16,6 +17,9 @@ out
|
||||||
org.*
|
org.*
|
||||||
bin
|
bin
|
||||||
|
|
||||||
|
#gradle
|
||||||
|
.gradle
|
||||||
|
|
||||||
#runtime
|
#runtime
|
||||||
run
|
run
|
||||||
run_server
|
run_server
|
||||||
|
|
34
build.gradle
34
build.gradle
|
@ -1,18 +1,24 @@
|
||||||
buildscript {
|
buildscript {
|
||||||
|
ext.kotlin_version = '1.2.20'
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
maven { url = "http://files.minecraftforge.net/maven" }
|
maven { url = "http://files.minecraftforge.net/maven" }
|
||||||
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
||||||
|
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.4'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
apply plugin: 'kotlin'
|
||||||
apply plugin: 'net.minecraftforge.gradle.forge'
|
apply plugin: 'net.minecraftforge.gradle.forge'
|
||||||
|
apply plugin: 'com.github.johnrengelman.shadow'
|
||||||
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
||||||
|
|
||||||
|
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
group = "arcanitor.civilengineering" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
group = "ivilengineering" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||||
archivesBaseName = "CivilEngineering"
|
archivesBaseName = "CivilEngineering"
|
||||||
|
|
||||||
sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
|
sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
|
||||||
|
@ -33,7 +39,19 @@ minecraft {
|
||||||
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
|
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
maven {
|
||||||
|
url = 'http://unascribed.com/maven/releases'
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
url "http://maven.shadowfacts.net/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
compile group: "net.shadowfacts", name: "Forgelin", version: "1.6.0"
|
||||||
|
compile group: 'io.github.microutils', name: 'kotlin-logging', version: '+'
|
||||||
// you may put jars on which you depend on in ./libs
|
// you may put jars on which you depend on in ./libs
|
||||||
// or you may define them like so..
|
// or you may define them like so..
|
||||||
//compile "some.group:artifact:version:classifier"
|
//compile "some.group:artifact:version:classifier"
|
||||||
|
@ -57,6 +75,16 @@ dependencies {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
relocate 'org.jetbrains.annotations', 'ivilengineering.jetbrains.annotations'
|
||||||
|
classifier ''
|
||||||
|
configurations = [project.configurations.shadow]
|
||||||
|
}
|
||||||
|
|
||||||
|
reobf {
|
||||||
|
shadowJar { mappingType = 'SEARGE' }
|
||||||
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
// this will ensure that this task is redone when the versions change.
|
// this will ensure that this task is redone when the versions change.
|
||||||
inputs.property "version", project.version
|
inputs.property "version", project.version
|
||||||
|
@ -75,3 +103,7 @@ processResources {
|
||||||
exclude 'mcmod.info'
|
exclude 'mcmod.info'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
|
}
|
|
@ -1,57 +0,0 @@
|
||||||
package arcanitor.civilengineering;
|
|
||||||
|
|
||||||
import arcanitor.civilengineering.eventhandlers.FMLEventHandler;
|
|
||||||
import arcanitor.civilengineering.bridge.MessageHandler;
|
|
||||||
import arcanitor.civilengineering.bridge.ServerChatHelper;
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
import net.minecraftforge.fml.common.event.*;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
@Mod(
|
|
||||||
modid = CivilEngineering.MODID,
|
|
||||||
name = CivilEngineering.NAME,
|
|
||||||
version = CivilEngineering.VERSION,
|
|
||||||
serverSideOnly = true,
|
|
||||||
useMetadata = true,
|
|
||||||
acceptableRemoteVersions = "*"
|
|
||||||
)
|
|
||||||
public class CivilEngineering {
|
|
||||||
public static final String MODID = "civilengineering";
|
|
||||||
public static final String NAME = "Civil Engineering";
|
|
||||||
public static final String VERSION = "0.0.1";
|
|
||||||
|
|
||||||
@Mod.Instance(value = CivilEngineering.MODID)
|
|
||||||
public static CivilEngineering instance;
|
|
||||||
|
|
||||||
public static Logger logger;
|
|
||||||
public static Thread MessageNetworkThread = new Thread(new MessageHandler());
|
|
||||||
|
|
||||||
@Mod.EventHandler
|
|
||||||
public void preInit(FMLPreInitializationEvent event) {
|
|
||||||
logger = event.getModLog();
|
|
||||||
|
|
||||||
FMLEventHandler.preInit(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mod.EventHandler
|
|
||||||
public void init(FMLInitializationEvent event) {
|
|
||||||
logger.info("Bridge building init.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mod.EventHandler
|
|
||||||
public void postInit(FMLPostInitializationEvent event) {
|
|
||||||
FMLEventHandler.postInit(event);
|
|
||||||
MinecraftForge.EVENT_BUS.register(ServerChatHelper.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mod.EventHandler
|
|
||||||
public void serverStarting(FMLServerStartingEvent event){
|
|
||||||
FMLEventHandler.serverStarting(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mod.EventHandler
|
|
||||||
public void serverStopping(FMLServerStoppingEvent event) {
|
|
||||||
FMLEventHandler.serverStopping(event);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package arcanitor.civilengineering.bridge;
|
|
||||||
|
|
||||||
import arcanitor.civilengineering.CivilEngineering;
|
|
||||||
import arcanitor.civilengineering.Config;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
public class ApiMessage {
|
|
||||||
private String text = "";
|
|
||||||
private String channel = "";
|
|
||||||
private String username = "";
|
|
||||||
private String userid = "";
|
|
||||||
private String avatar = "";
|
|
||||||
private String gateway = "";
|
|
||||||
private String event = "";
|
|
||||||
|
|
||||||
public ApiMessage(String user, String msg) {
|
|
||||||
this.username = user;
|
|
||||||
this.text = msg;
|
|
||||||
this.gateway = Config.gateway;
|
|
||||||
|
|
||||||
}
|
|
||||||
public ApiMessage(String user, String msg, String event) {
|
|
||||||
this.username = user;
|
|
||||||
this.text = msg;
|
|
||||||
this.event = event;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ApiMessage decode(String json) {
|
|
||||||
Gson gson = new Gson();
|
|
||||||
ApiMessage msg = gson.fromJson(json, ApiMessage.class);
|
|
||||||
return msg;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String encode() {
|
|
||||||
Gson gson = new Gson();
|
|
||||||
return gson.toJson(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return this.username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMessage() {
|
|
||||||
return this.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEvent() {
|
|
||||||
return this.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
package arcanitor.civilengineering.bridge;
|
|
||||||
|
|
||||||
import arcanitor.civilengineering.CivilEngineering;
|
|
||||||
import arcanitor.civilengineering.Config;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
|
|
||||||
import static java.lang.Thread.sleep;
|
|
||||||
|
|
||||||
public class MessageHandler implements Runnable {
|
|
||||||
|
|
||||||
public static ConcurrentLinkedQueue<ApiMessage> xmitQueue = new ConcurrentLinkedQueue<>();
|
|
||||||
public static ConcurrentLinkedQueue<ApiMessage> rcvQueue = new ConcurrentLinkedQueue<>();
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
CivilEngineering.logger.info("Connecting to bridge server @ "+Config.connectURL);
|
|
||||||
try {
|
|
||||||
while(true) {
|
|
||||||
transmitFromQueue();
|
|
||||||
receiveToQueue();
|
|
||||||
sleep(1000);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
if (e instanceof InterruptedException) {
|
|
||||||
CivilEngineering.logger.info("Connection closed.");
|
|
||||||
} else if (e instanceof IOException) {
|
|
||||||
CivilEngineering.logger.error("Error connecting to bridge server!");
|
|
||||||
CivilEngineering.logger.error(e.getMessage());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void transmitFromQueue() throws IOException {
|
|
||||||
ApiMessage nextMessage = xmitQueue.poll();
|
|
||||||
while(nextMessage != null) {
|
|
||||||
//open a connection
|
|
||||||
URL url = new URL(Config.connectURL + "/api/message");
|
|
||||||
URLConnection urlConnection = url.openConnection();
|
|
||||||
HttpURLConnection connection = (HttpURLConnection)urlConnection;
|
|
||||||
|
|
||||||
//configure the connection
|
|
||||||
connection.setAllowUserInteraction(false);
|
|
||||||
connection.setInstanceFollowRedirects(true);
|
|
||||||
connection.setRequestProperty("Content-Type","application/json");
|
|
||||||
connection.setRequestMethod("POST");
|
|
||||||
if (Config.authToken != null) {
|
|
||||||
connection.setRequestProperty ("Authorization", "Bearer " + Config.authToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
//encode the ApiMessage for sending
|
|
||||||
String json = nextMessage.encode();
|
|
||||||
|
|
||||||
//send the message
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
DataOutputStream post = new DataOutputStream(connection.getOutputStream());
|
|
||||||
post.writeBytes(json);
|
|
||||||
post.flush();
|
|
||||||
post.close();
|
|
||||||
|
|
||||||
if (connection.getResponseCode()!=200) {
|
|
||||||
CivilEngineering.logger.error("Server returned "+connection.getResponseCode());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
nextMessage = xmitQueue.poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
private void receiveToQueue() throws IOException {
|
|
||||||
ApiMessage[] messages;
|
|
||||||
|
|
||||||
//open a connection
|
|
||||||
URL url = new URL(Config.connectURL + "/api/messages");
|
|
||||||
HttpURLConnection con = (HttpURLConnection)url.openConnection();
|
|
||||||
|
|
||||||
//configure the connection
|
|
||||||
con.setAllowUserInteraction(false);
|
|
||||||
con.setInstanceFollowRedirects(true);
|
|
||||||
if (Config.authToken != null) {
|
|
||||||
con.setRequestProperty ("Authorization", "Bearer " + Config.authToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
//read the messages
|
|
||||||
BufferedReader input = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
|
||||||
StringBuilder data = new StringBuilder();
|
|
||||||
String line;
|
|
||||||
while((line = input.readLine( )) != null) {
|
|
||||||
data.append(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
//decode the messages
|
|
||||||
Gson gson = new Gson();
|
|
||||||
messages = gson.fromJson(data.toString(),ApiMessage[].class);
|
|
||||||
|
|
||||||
//enqueue the messages
|
|
||||||
if(messages.length>0) for (ApiMessage msg : messages) rcvQueue.add(msg);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
package arcanitor.civilengineering.bridge;
|
|
||||||
|
|
||||||
import arcanitor.civilengineering.CivilEngineering;
|
|
||||||
import arcanitor.civilengineering.Config;
|
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
|
|
||||||
import static java.lang.Thread.sleep;
|
|
||||||
|
|
||||||
public class OutgoingMessageHandler implements Runnable {
|
|
||||||
public static ConcurrentLinkedQueue<ApiMessage> queue = new ConcurrentLinkedQueue();
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
CivilEngineering.logger.info("Sending network thread starting");
|
|
||||||
try {
|
|
||||||
while(true) {
|
|
||||||
ApiMessage nextMessage = queue.poll();
|
|
||||||
if (nextMessage!=null) {
|
|
||||||
int response = postMessage(nextMessage);
|
|
||||||
if (response != 200) {
|
|
||||||
CivilEngineering.logger.error("Server returned error "+response);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sleep(50);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (e instanceof InterruptedException) {
|
|
||||||
CivilEngineering.logger.info("Sending connection closed.");
|
|
||||||
} else if (e instanceof IOException) {
|
|
||||||
CivilEngineering.MessageNetworkThread.interrupt();
|
|
||||||
CivilEngineering.logger.error("Error connecting to bridge server!");
|
|
||||||
CivilEngineering.logger.error(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int postMessage(ApiMessage message) throws IOException {
|
|
||||||
|
|
||||||
//open a connection
|
|
||||||
URL url = new URL(Config.connectURL + "/api/message");
|
|
||||||
URLConnection urlConnection = url.openConnection();
|
|
||||||
HttpURLConnection connection = (HttpURLConnection)urlConnection;
|
|
||||||
|
|
||||||
//configure the connection
|
|
||||||
connection.setAllowUserInteraction(false);
|
|
||||||
connection.setInstanceFollowRedirects(true);
|
|
||||||
connection.setRequestProperty("Content-Type","application/json");
|
|
||||||
connection.setRequestMethod("POST");
|
|
||||||
if (Config.authToken != null) {
|
|
||||||
connection.setRequestProperty ("Authorization", "Bearer " + Config.authToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
//encode the ApiMessage for sending
|
|
||||||
String json = message.encode();
|
|
||||||
|
|
||||||
//send the message
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
DataOutputStream post = new DataOutputStream(connection.getOutputStream());
|
|
||||||
post.writeBytes(json);
|
|
||||||
post.flush();
|
|
||||||
post.close();
|
|
||||||
|
|
||||||
return connection.getResponseCode();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package arcanitor.civilengineering.bridge;
|
|
||||||
|
|
||||||
import arcanitor.civilengineering.bridge.ApiMessage;
|
|
||||||
import arcanitor.civilengineering.bridge.MessageHandler;
|
|
||||||
import net.minecraft.util.text.TextComponentString;
|
|
||||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
|
||||||
|
|
||||||
public class ServerChatHelper {
|
|
||||||
//public static ConcurrentLinkedQueue<ApiMessage> messages = new ConcurrentLinkedQueue();
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onServerUpdate(TickEvent.ServerTickEvent event) {
|
|
||||||
ApiMessage nextMessage = MessageHandler.rcvQueue.poll();
|
|
||||||
|
|
||||||
if (nextMessage != null) {
|
|
||||||
String user = nextMessage.getUsername();
|
|
||||||
String text = nextMessage.getMessage().trim();
|
|
||||||
|
|
||||||
String message;
|
|
||||||
|
|
||||||
if (!text.isEmpty()) {
|
|
||||||
if (nextMessage.getEvent().equals("user_action")) {
|
|
||||||
message = "* " + user + " " + text;
|
|
||||||
} else {
|
|
||||||
message = "<" + user + "> " + text;
|
|
||||||
}
|
|
||||||
FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().sendMessage(new TextComponentString(message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package arcanitor.civilengineering.command;
|
|
||||||
|
|
||||||
import arcanitor.civilengineering.CivilEngineering;
|
|
||||||
import arcanitor.civilengineering.bridge.MessageHandler;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import net.minecraft.command.CommandBase;
|
|
||||||
import net.minecraft.command.ICommandSender;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class BridgeCommand extends CommandBase {
|
|
||||||
private final List<String> aliases;
|
|
||||||
|
|
||||||
public BridgeCommand(){
|
|
||||||
aliases = Lists.newArrayList(CivilEngineering.MODID,"bridge","BRIDGE");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nonnull
|
|
||||||
public String getName() {
|
|
||||||
return "bridge";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsage(ICommandSender sender) {
|
|
||||||
return "bridge <connect|disconnect>";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nonnull
|
|
||||||
public List<String> getAliases() {
|
|
||||||
return aliases;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(MinecraftServer server, ICommandSender sender, String[] args) /*throws CommandException*/ {
|
|
||||||
if (args.length < 1) {
|
|
||||||
//throw new WrongUsageException("")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String cmd = args[0];
|
|
||||||
if (cmd.toLowerCase().equals("connect")) {
|
|
||||||
if(!CivilEngineering.MessageNetworkThread.isAlive()) {
|
|
||||||
CivilEngineering.MessageNetworkThread = new Thread(new MessageHandler());
|
|
||||||
CivilEngineering.MessageNetworkThread.start();
|
|
||||||
}
|
|
||||||
} else if (cmd.toLowerCase().equals("disconnect")) {
|
|
||||||
CivilEngineering.MessageNetworkThread.interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package arcanitor.civilengineering.eventhandlers;
|
|
||||||
|
|
||||||
import arcanitor.civilengineering.bridge.ApiMessage;
|
|
||||||
import arcanitor.civilengineering.bridge.MessageHandler;
|
|
||||||
import net.minecraftforge.event.ServerChatEvent;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
|
|
||||||
@Mod.EventBusSubscriber
|
|
||||||
public class ChatMessageHandler {
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void handleServerChatEvent (ServerChatEvent event) {
|
|
||||||
String message = event.getMessage().trim();
|
|
||||||
if (!message.isEmpty())
|
|
||||||
MessageHandler.xmitQueue.add(new ApiMessage(event.getUsername(),message));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
package arcanitor.civilengineering.eventhandlers;
|
|
||||||
|
|
||||||
import arcanitor.civilengineering.Config;
|
|
||||||
import arcanitor.civilengineering.bridge.ApiMessage;
|
|
||||||
import arcanitor.civilengineering.bridge.MessageHandler;
|
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraftforge.event.entity.living.LivingDeathEvent;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
|
|
||||||
@Mod.EventBusSubscriber
|
|
||||||
public class DeathEventHandler {
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void handleLivingDeathEvent (LivingDeathEvent event) {
|
|
||||||
if(Config.relayDeathEvents) {
|
|
||||||
EntityLivingBase entity = event.getEntityLiving();
|
|
||||||
if (entity instanceof EntityPlayer) {
|
|
||||||
String message = entity.getCombatTracker().getDeathMessage().getUnformattedText();
|
|
||||||
MessageHandler.xmitQueue.add(new ApiMessage("Server",message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package arcanitor.civilengineering.eventhandlers;
|
|
||||||
|
|
||||||
|
|
||||||
import arcanitor.civilengineering.CivilEngineering;
|
|
||||||
import arcanitor.civilengineering.Config;
|
|
||||||
import arcanitor.civilengineering.command.BridgeCommand;
|
|
||||||
import net.minecraftforge.common.config.Configuration;
|
|
||||||
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
|
||||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
|
||||||
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
|
|
||||||
import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class FMLEventHandler {
|
|
||||||
public static Configuration config;
|
|
||||||
|
|
||||||
public static void preInit(FMLPreInitializationEvent event) {
|
|
||||||
CivilEngineering.logger.info("Reading bridge blueprints...");
|
|
||||||
File directory = event.getModConfigurationDirectory();
|
|
||||||
config = new Configuration(new File(directory.getPath(), "CivilEngineering.cfg"));
|
|
||||||
Config.readConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void postInit(FMLPostInitializationEvent event) {
|
|
||||||
if (config.hasChanged()) {
|
|
||||||
config.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serverStarting(FMLServerStartingEvent event) {
|
|
||||||
event.registerServerCommand(new BridgeCommand());
|
|
||||||
CivilEngineering.MessageNetworkThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serverStopping(FMLServerStoppingEvent event) {
|
|
||||||
CivilEngineering.MessageNetworkThread.interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package arcanitor.civilengineering.eventhandlers;
|
|
||||||
|
|
||||||
import arcanitor.civilengineering.bridge.ApiMessage;
|
|
||||||
import arcanitor.civilengineering.bridge.MessageHandler;
|
|
||||||
import net.minecraft.command.server.CommandEmote;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraftforge.event.CommandEvent;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
|
|
||||||
@Mod.EventBusSubscriber
|
|
||||||
public class UserActionHandler {
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void handleCommandEvent(CommandEvent event) {
|
|
||||||
if(event.getCommand() instanceof CommandEmote && event.getSender() instanceof EntityPlayer) {
|
|
||||||
String[] args = event.getParameters();
|
|
||||||
|
|
||||||
String user = event.getSender().getName();
|
|
||||||
String message = "";
|
|
||||||
|
|
||||||
for(String word:args) {
|
|
||||||
message = message + " " + word;
|
|
||||||
}
|
|
||||||
message = message.trim();
|
|
||||||
|
|
||||||
MessageHandler.xmitQueue.add(new ApiMessage(user,message,"user_action"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
package civilengineering
|
||||||
|
|
||||||
|
import civilengineering.bridge.MessageHandler
|
||||||
|
import civilengineering.bridge.ServerChatHelper
|
||||||
|
import civilengineering.command.BridgeCommand
|
||||||
|
import civilengineering.eventhandlers.ChatMessageHandler
|
||||||
|
import civilengineering.eventhandlers.DeathEventHandler
|
||||||
|
import civilengineering.eventhandlers.UserActionHandler
|
||||||
|
import net.minecraftforge.common.MinecraftForge
|
||||||
|
import net.minecraftforge.common.config.Configuration
|
||||||
|
import net.minecraftforge.fml.common.Mod
|
||||||
|
import net.minecraftforge.fml.common.event.*
|
||||||
|
import org.apache.logging.log4j.Level
|
||||||
|
import org.apache.logging.log4j.Logger
|
||||||
|
import org.apache.logging.log4j.Marker
|
||||||
|
import org.apache.logging.log4j.message.Message
|
||||||
|
import org.apache.logging.log4j.message.MessageFactory
|
||||||
|
import org.apache.logging.log4j.message.SimpleMessageFactory
|
||||||
|
import org.apache.logging.log4j.simple.SimpleLogger
|
||||||
|
import org.apache.logging.log4j.spi.AbstractLogger
|
||||||
|
import org.apache.logging.log4j.util.PropertiesUtil
|
||||||
|
import java.io.File
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
import java.time.format.DateTimeFormatterBuilder
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
const val MODID = "civilengineering"
|
||||||
|
const val NAME = "Civil Engineering"
|
||||||
|
const val VERSION = "0.0.1"
|
||||||
|
|
||||||
|
@Mod(
|
||||||
|
modid = MODID,
|
||||||
|
name = NAME, version = VERSION,
|
||||||
|
serverSideOnly = true,
|
||||||
|
useMetadata = true,
|
||||||
|
acceptableRemoteVersions = "*",
|
||||||
|
modLanguageAdapter = "net.shadowfacts.forgelin.KotlinAdapter"
|
||||||
|
)
|
||||||
|
object CivilEngineering {
|
||||||
|
init {
|
||||||
|
}
|
||||||
|
|
||||||
|
var config: Configuration = Configuration()
|
||||||
|
// var messageNetworkThread = Thread(MessageHandler())
|
||||||
|
var logger: Logger = SimpleLogger ("",
|
||||||
|
Level.OFF,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
SimpleMessageFactory(),
|
||||||
|
PropertiesUtil(Properties()),
|
||||||
|
System.out)
|
||||||
|
|
||||||
|
@Mod.EventHandler
|
||||||
|
fun preInit(event: FMLPreInitializationEvent) {
|
||||||
|
logger = event.modLog
|
||||||
|
logger!!.info("loading logger")
|
||||||
|
|
||||||
|
CivilEngineering.logger!!.info("Reading bridge blueprints...")
|
||||||
|
val directory = event.modConfigurationDirectory
|
||||||
|
config = Configuration(File(directory.path, "CivilEngineering.cfg"))
|
||||||
|
Config.readConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mod.EventHandler
|
||||||
|
fun init(event: FMLInitializationEvent) {
|
||||||
|
logger!!.info("Bridge building init.")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mod.EventHandler
|
||||||
|
fun postInit(event: FMLPostInitializationEvent) {
|
||||||
|
if (config.hasChanged()) {
|
||||||
|
config.save()
|
||||||
|
}
|
||||||
|
MinecraftForge.EVENT_BUS.register(ServerChatHelper::class.java)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mod.EventHandler
|
||||||
|
fun serverStarting(event: FMLServerStartingEvent) {
|
||||||
|
event.registerServerCommand(BridgeCommand())
|
||||||
|
logger!!.info("Bridge building starting.")
|
||||||
|
MessageHandler.start()
|
||||||
|
|
||||||
|
//maybe try registering them manually
|
||||||
|
MinecraftForge.EVENT_BUS.register(ChatMessageHandler())
|
||||||
|
MinecraftForge.EVENT_BUS.register(DeathEventHandler())
|
||||||
|
MinecraftForge.EVENT_BUS.register(UserActionHandler())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mod.EventHandler
|
||||||
|
fun serverStopping(event: FMLServerStoppingEvent) {
|
||||||
|
logger!!.info("Bridge shutting down.")
|
||||||
|
MessageHandler.stop()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,76 +1,75 @@
|
||||||
package arcanitor.civilengineering;
|
package civilengineering
|
||||||
|
|
||||||
import arcanitor.civilengineering.eventhandlers.FMLEventHandler;
|
import net.minecraftforge.common.config.Configuration
|
||||||
import net.minecraftforge.common.config.Configuration;
|
import org.apache.logging.log4j.Level
|
||||||
import org.apache.logging.log4j.Level;
|
|
||||||
|
|
||||||
public class Config {
|
object Config {
|
||||||
private static final String CATEGORY_RELAY_OPTIONS = "relay_options";
|
private val CATEGORY_RELAY_OPTIONS = "relay_options"
|
||||||
private static final String CATEGORY_CONNECTION = "connection";
|
private val CATEGORY_CONNECTION = "connection"
|
||||||
|
|
||||||
public static boolean relayDeathEvents = false;
|
var relayDeathEvents = false
|
||||||
public static boolean relayAdvancements = false; //unused for now
|
var relayAdvancements = false //unused for now
|
||||||
public static boolean relayJoinLeave = false;
|
var relayJoinLeave = false
|
||||||
|
|
||||||
public static String connectURL = "localhost";
|
var connectURL = "http://localhost"
|
||||||
public static String authToken = "";
|
var authToken = ""
|
||||||
public static String gateway = "";
|
var gateway = ""
|
||||||
|
|
||||||
public static void readConfig() {
|
fun readConfig() {
|
||||||
Configuration config = FMLEventHandler.config;
|
|
||||||
|
val config = CivilEngineering.config
|
||||||
try {
|
try {
|
||||||
config.load();
|
config.load()
|
||||||
initConfig(config);
|
initConfig(config)
|
||||||
} catch (Exception expt) {
|
} catch (e: Exception) {
|
||||||
CivilEngineering.logger.log(Level.ERROR,"Could not read config file!", expt);
|
CivilEngineering.logger!!.log(Level.ERROR, "Could not read config file!", e)
|
||||||
} finally {
|
} finally {
|
||||||
if (config.hasChanged()) {
|
if (config.hasChanged()) {
|
||||||
config.save();
|
config.save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initConfig(Configuration cfg) {
|
private fun initConfig(cfg: Configuration) {
|
||||||
cfg.addCustomCategoryComment(CATEGORY_RELAY_OPTIONS,"Relay options");
|
cfg.addCustomCategoryComment(CATEGORY_RELAY_OPTIONS, "Relay options")
|
||||||
cfg.addCustomCategoryComment(CATEGORY_CONNECTION,"Connection settings");
|
cfg.addCustomCategoryComment(CATEGORY_CONNECTION, "Connection settings")
|
||||||
relayDeathEvents = cfg.getBoolean(
|
relayDeathEvents = cfg.getBoolean(
|
||||||
"relayDeathEvents",
|
"relayDeathEvents",
|
||||||
CATEGORY_RELAY_OPTIONS,
|
CATEGORY_RELAY_OPTIONS,
|
||||||
false,
|
false,
|
||||||
"Relay player death messages"
|
"Relay player death messages"
|
||||||
);
|
)
|
||||||
relayAdvancements = cfg.getBoolean(
|
relayAdvancements = cfg.getBoolean(
|
||||||
"relayAdvancements",
|
"relayAdvancements",
|
||||||
CATEGORY_RELAY_OPTIONS,
|
CATEGORY_RELAY_OPTIONS,
|
||||||
false,
|
false,
|
||||||
"Relay player advancements [NOT IMPLEMENTED]"
|
"Relay player advancements [NOT IMPLEMENTED]"
|
||||||
);
|
)
|
||||||
relayJoinLeave = cfg.getBoolean(
|
relayJoinLeave = cfg.getBoolean(
|
||||||
"relayJoinLeave",
|
"relayJoinLeave",
|
||||||
CATEGORY_RELAY_OPTIONS,
|
CATEGORY_RELAY_OPTIONS,
|
||||||
false,
|
false,
|
||||||
"Relay when a player joins or leaves the game [NOT IMPLEMENTED]"
|
"Relay when a player joins or leaves the game [NOT IMPLEMENTED]"
|
||||||
);
|
)
|
||||||
|
|
||||||
connectURL = cfg.getString(
|
connectURL = cfg.getString(
|
||||||
"connectURL",
|
"connectURL",
|
||||||
CATEGORY_CONNECTION,
|
CATEGORY_CONNECTION,
|
||||||
"http://example.com:1234",
|
"http://example.com:1234",
|
||||||
"The URL or IP address of the bridge server, ex. http://example.com:1234"
|
"The URL or IP address of the bridge server, ex. http://example.com:1234"
|
||||||
);
|
)
|
||||||
authToken = cfg.getString(
|
authToken = cfg.getString(
|
||||||
"auth_token",
|
"auth_token",
|
||||||
CATEGORY_CONNECTION,
|
CATEGORY_CONNECTION,
|
||||||
"",
|
"",
|
||||||
"Auth token used to connect to the bridge server"
|
"Auth token used to connect to the bridge server"
|
||||||
);
|
)
|
||||||
gateway = cfg.getString(
|
gateway = cfg.getString(
|
||||||
"gateway",
|
"gateway",
|
||||||
CATEGORY_CONNECTION,
|
CATEGORY_CONNECTION,
|
||||||
"",
|
"",
|
||||||
"MatterBridge gateway"
|
"MatterBridge gateway"
|
||||||
);
|
)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package civilengineering.bridge
|
||||||
|
|
||||||
|
import civilengineering.Config
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
data class ApiMessage (
|
||||||
|
val text: String = "",
|
||||||
|
val channel: String = "",
|
||||||
|
val username: String = "",
|
||||||
|
val userid: String = "",
|
||||||
|
val avatar: String = "",
|
||||||
|
val account: String = "",
|
||||||
|
val event: String = "",
|
||||||
|
val protocol: String = "",
|
||||||
|
val gateway: String = "",
|
||||||
|
// val timestamp: Date,
|
||||||
|
val id: String = ""
|
||||||
|
// val Extra: Any? = null
|
||||||
|
) {
|
||||||
|
fun encode(): String {
|
||||||
|
return gson.toJson(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val gson = Gson()
|
||||||
|
|
||||||
|
fun decode(json: String): ApiMessage {
|
||||||
|
return gson.fromJson(json, ApiMessage::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package civilengineering.bridge
|
||||||
|
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by nikky on 20/01/18.
|
||||||
|
* @author Nikky
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CancellableConnectionFollowThread (val httpConnClosure: () -> HttpURLConnection, val mhandler: (String) -> Unit): Thread() {
|
||||||
|
val cancelGuard = Object()
|
||||||
|
var waitingOnNetwork = true
|
||||||
|
var cancelled = false
|
||||||
|
val httpConn = httpConnClosure()
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
try {
|
||||||
|
httpConn.allowUserInteraction = false
|
||||||
|
httpConn.instanceFollowRedirects = true
|
||||||
|
httpConn.requestMethod = "GET"
|
||||||
|
|
||||||
|
InputStreamReader(httpConn.inputStream).useLines {
|
||||||
|
it.forEach{
|
||||||
|
synchronized(cancelGuard) {
|
||||||
|
if (cancelled) return
|
||||||
|
waitingOnNetwork = false
|
||||||
|
}
|
||||||
|
mhandler(it)
|
||||||
|
synchronized(cancelGuard) {
|
||||||
|
if (cancelled) return
|
||||||
|
waitingOnNetwork = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
} finally {
|
||||||
|
httpConn.disconnect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun abort() {
|
||||||
|
synchronized(cancelGuard) {
|
||||||
|
httpConn.disconnect()
|
||||||
|
cancelled = true
|
||||||
|
if (waitingOnNetwork) stop()
|
||||||
|
}
|
||||||
|
join()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,187 @@
|
||||||
|
package civilengineering.bridge
|
||||||
|
|
||||||
|
import civilengineering.CivilEngineering
|
||||||
|
import civilengineering.Config
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.DataOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.lang.Thread.sleep
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
import java.net.URL
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
|
|
||||||
|
class MessageHandler : Runnable {
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
CivilEngineering.logger!!.info("Connecting to bridge server @ " + Config.connectURL)
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
transmitFromQueue()
|
||||||
|
// receiveToQueue()
|
||||||
|
sleep(1000)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
|
||||||
|
if (e is InterruptedException) {
|
||||||
|
CivilEngineering.logger!!.info("Connection closed.")
|
||||||
|
} else if (e is IOException) {
|
||||||
|
CivilEngineering.logger!!.error("Error connecting to bridge server!")
|
||||||
|
CivilEngineering.logger!!.error(e.message)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
private fun transmitFromQueue() {
|
||||||
|
var nextMessage: ApiMessage? = xmitQueue.poll()
|
||||||
|
while (nextMessage != null) {
|
||||||
|
//open a connection
|
||||||
|
val url = URL(Config.connectURL + "/api/message")
|
||||||
|
val urlConnection = url.openConnection()
|
||||||
|
val connection = urlConnection as HttpURLConnection
|
||||||
|
|
||||||
|
//configure the connection
|
||||||
|
connection.allowUserInteraction = false
|
||||||
|
connection.instanceFollowRedirects = true
|
||||||
|
connection.setRequestProperty("Content-Type", "application/json")
|
||||||
|
connection.requestMethod = "POST"
|
||||||
|
if (Config.authToken.isNotEmpty()) {
|
||||||
|
connection.setRequestProperty("Authorization", "Bearer " + Config.authToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
//encode the ApiMessage for sending
|
||||||
|
val json = nextMessage.encode()
|
||||||
|
|
||||||
|
//send the message
|
||||||
|
connection.doOutput = true
|
||||||
|
val post = DataOutputStream(connection.outputStream)
|
||||||
|
post.writeBytes(json)
|
||||||
|
post.flush()
|
||||||
|
post.close()
|
||||||
|
|
||||||
|
if (connection.responseCode != 200) {
|
||||||
|
CivilEngineering.logger!!.error("Server returned " + connection.responseCode)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
nextMessage = xmitQueue.poll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
private fun receiveToQueue() {
|
||||||
|
val messages: Array<ApiMessage>
|
||||||
|
|
||||||
|
//open a connection
|
||||||
|
val url = URL(Config.connectURL + "/api/messages")
|
||||||
|
val con = url.openConnection() as HttpURLConnection
|
||||||
|
|
||||||
|
//configure the connection
|
||||||
|
con.allowUserInteraction = false
|
||||||
|
con.instanceFollowRedirects = true
|
||||||
|
if (Config.authToken.isNotEmpty()) {
|
||||||
|
con.setRequestProperty("Authorization", "Bearer " + Config.authToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
//read the messages
|
||||||
|
val input = BufferedReader(InputStreamReader(con.inputStream))
|
||||||
|
val data = StringBuilder()
|
||||||
|
var line: String?
|
||||||
|
while (true) {
|
||||||
|
line = input.readLine()
|
||||||
|
if (line == null) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
data.append(line)
|
||||||
|
}
|
||||||
|
//decode the messages
|
||||||
|
val gson = Gson()
|
||||||
|
messages = gson.fromJson(data.toString(), Array<ApiMessage>::class.java)
|
||||||
|
|
||||||
|
//enqueue the messages
|
||||||
|
if (messages.isNotEmpty()) for (msg in messages) rcvQueue.add(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private fun createThread(): CancellableConnectionFollowThread {
|
||||||
|
return CancellableConnectionFollowThread(
|
||||||
|
{
|
||||||
|
CivilEngineering.logger!!.info("Connecting to bridge server @ " + Config.connectURL)
|
||||||
|
val httpConn = URL(Config.connectURL + "/api/stream").openConnection() as HttpURLConnection
|
||||||
|
if (Config.authToken.isNotBlank())
|
||||||
|
httpConn.setRequestProperty("Authorization", "Bearer ${Config.authToken}")
|
||||||
|
httpConn
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rcvQueue.add(
|
||||||
|
ApiMessage.decode(it)
|
||||||
|
)
|
||||||
|
CivilEngineering.logger!!.trace("received: " + it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var cancellableThread: CancellableConnectionFollowThread = createThread()
|
||||||
|
|
||||||
|
private var xmitQueue = ConcurrentLinkedQueue<ApiMessage>()
|
||||||
|
|
||||||
|
var rcvQueue = ConcurrentLinkedQueue<ApiMessage>()
|
||||||
|
|
||||||
|
fun transmit(msg: ApiMessage) {
|
||||||
|
CivilEngineering.logger!!.info("transmitting " + msg)
|
||||||
|
transmitMessage(msg)
|
||||||
|
//TODO: create thread with Runnable(sendstuff).execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stop() {
|
||||||
|
cancellableThread.abort()
|
||||||
|
CivilEngineering.logger!!.info("bridge closed ")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun start(): Boolean {
|
||||||
|
if (cancellableThread.isInterrupted) {
|
||||||
|
CivilEngineering.logger!!.info("brebuilding bridge")
|
||||||
|
cancellableThread = createThread()
|
||||||
|
}
|
||||||
|
if (!cancellableThread.isAlive) {
|
||||||
|
cancellableThread.start()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
private fun transmitMessage(message: ApiMessage) {
|
||||||
|
//open a connection
|
||||||
|
val url = URL(Config.connectURL + "/api/message")
|
||||||
|
val urlConnection = url.openConnection()
|
||||||
|
val connection = urlConnection as HttpURLConnection
|
||||||
|
|
||||||
|
//configure the connection
|
||||||
|
connection.allowUserInteraction = false
|
||||||
|
connection.instanceFollowRedirects = true
|
||||||
|
connection.setRequestProperty("Content-Type", "application/json")
|
||||||
|
connection.requestMethod = "POST"
|
||||||
|
if (Config.authToken.isNotEmpty()) {
|
||||||
|
connection.setRequestProperty("Authorization", "Bearer " + Config.authToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
//encode the ApiMessage for sending
|
||||||
|
val json = message.encode()
|
||||||
|
|
||||||
|
//send the message
|
||||||
|
connection.doOutput = true
|
||||||
|
val post = DataOutputStream(connection.outputStream)
|
||||||
|
post.writeBytes(json)
|
||||||
|
post.flush()
|
||||||
|
post.close()
|
||||||
|
|
||||||
|
if (connection.responseCode != 200) {
|
||||||
|
CivilEngineering.logger!!.error("Server returned " + connection.responseCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package civilengineering.bridge
|
||||||
|
|
||||||
|
import civilengineering.CivilEngineering
|
||||||
|
import net.minecraft.util.text.TextComponentString
|
||||||
|
import net.minecraftforge.fml.common.FMLCommonHandler
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||||
|
import net.minecraftforge.fml.common.gameevent.TickEvent
|
||||||
|
|
||||||
|
object ServerChatHelper {
|
||||||
|
//public static ConcurrentLinkedQueue<ApiMessage> messages = new ConcurrentLinkedQueue();
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onServerUpdate(event: TickEvent.ServerTickEvent) {
|
||||||
|
if(MessageHandler.rcvQueue.isNotEmpty())
|
||||||
|
CivilEngineering.logger!!.info("incoming: " + MessageHandler.rcvQueue.toString())
|
||||||
|
val nextMessage = MessageHandler.rcvQueue.poll()
|
||||||
|
|
||||||
|
if (nextMessage != null) {
|
||||||
|
val user = nextMessage.username
|
||||||
|
val text = nextMessage.text.trim()
|
||||||
|
|
||||||
|
val message: String
|
||||||
|
|
||||||
|
if (!text.isEmpty()) {
|
||||||
|
message = when(nextMessage.event) {
|
||||||
|
"user_action" -> "* $user $text"
|
||||||
|
else -> "<$user> $text"
|
||||||
|
}
|
||||||
|
FMLCommonHandler.instance().minecraftServerInstance.playerList.sendMessage(TextComponentString(message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package civilengineering.command
|
||||||
|
|
||||||
|
import civilengineering.CivilEngineering
|
||||||
|
import civilengineering.*
|
||||||
|
import civilengineering.CivilEngineering.logger
|
||||||
|
import civilengineering.bridge.MessageHandler
|
||||||
|
import com.google.common.collect.Lists
|
||||||
|
import net.minecraft.command.CommandBase
|
||||||
|
import net.minecraft.command.ICommandSender
|
||||||
|
import net.minecraft.server.MinecraftServer
|
||||||
|
|
||||||
|
|
||||||
|
class BridgeCommand : CommandBase() {
|
||||||
|
private val aliases: List<String>
|
||||||
|
|
||||||
|
init {
|
||||||
|
aliases = Lists.newArrayList(MODID, "bridge", "BRIDGE")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return "bridge"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUsage(sender: ICommandSender): String {
|
||||||
|
return "bridge <connect|disconnect>"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAliases(): List<String> {
|
||||||
|
return aliases
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun execute(server: MinecraftServer, sender: ICommandSender, args: Array<String>) /*throws CommandException*/ {
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
//throw new WrongUsageException("")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO: check if sender is OP or test if normal users cannot send this
|
||||||
|
|
||||||
|
|
||||||
|
val cmd = args[0].toLowerCase()
|
||||||
|
when (cmd) {
|
||||||
|
"connect" -> if (MessageHandler.start()) {
|
||||||
|
logger!!.info("connected to matterbridge")
|
||||||
|
} else {
|
||||||
|
logger!!.error("connection to matterbridge failed")
|
||||||
|
}
|
||||||
|
"disconnect" -> MessageHandler.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package civilengineering.eventhandlers
|
||||||
|
|
||||||
|
import civilengineering.bridge.ApiMessage
|
||||||
|
import civilengineering.bridge.MessageHandler
|
||||||
|
import net.minecraftforge.event.ServerChatEvent
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||||
|
|
||||||
|
class ChatMessageHandler {
|
||||||
|
@SubscribeEvent
|
||||||
|
fun handleServerChatEvent(event: ServerChatEvent) {
|
||||||
|
val message = event.message.trim { it <= ' ' }
|
||||||
|
if (!message.isEmpty())
|
||||||
|
MessageHandler.transmit(ApiMessage(event.username, message))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package civilengineering.eventhandlers
|
||||||
|
|
||||||
|
import civilengineering.Config
|
||||||
|
import civilengineering.bridge.ApiMessage
|
||||||
|
import civilengineering.bridge.MessageHandler
|
||||||
|
import net.minecraft.entity.EntityLivingBase
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraftforge.event.entity.living.LivingDeathEvent
|
||||||
|
import net.minecraftforge.fml.common.Mod
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||||
|
|
||||||
|
class DeathEventHandler {
|
||||||
|
@SubscribeEvent
|
||||||
|
fun handleLivingDeathEvent(event: LivingDeathEvent) {
|
||||||
|
if (Config.relayDeathEvents) {
|
||||||
|
val entity = event.entityLiving
|
||||||
|
if (entity is EntityPlayer) {
|
||||||
|
val message = entity.getCombatTracker().deathMessage.unformattedText
|
||||||
|
MessageHandler.transmit(ApiMessage("Server", message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package civilengineering.eventhandlers
|
||||||
|
|
||||||
|
import civilengineering.bridge.ApiMessage
|
||||||
|
import civilengineering.bridge.MessageHandler
|
||||||
|
import net.minecraft.command.server.CommandEmote
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraftforge.event.CommandEvent
|
||||||
|
import net.minecraftforge.fml.common.Mod
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||||
|
|
||||||
|
class UserActionHandler {
|
||||||
|
@SubscribeEvent
|
||||||
|
fun handleCommandEvent(event: CommandEvent) {
|
||||||
|
if (event.command is CommandEmote && event.sender is EntityPlayer) {
|
||||||
|
val args = event.parameters
|
||||||
|
|
||||||
|
val user = event.sender.name
|
||||||
|
var message = ""
|
||||||
|
|
||||||
|
for (word in args) {
|
||||||
|
message = message + " " + word
|
||||||
|
}
|
||||||
|
message = message.trim { it <= ' ' }
|
||||||
|
|
||||||
|
MessageHandler.transmit(ApiMessage(user, message, "user_action"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,6 @@
|
||||||
"description": "Minecraft Server Matterbridge link",
|
"description": "Minecraft Server Matterbridge link",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"mcversion": "1.12.2",
|
"mcversion": "1.12.2",
|
||||||
"authorList":["Arcanitor"],
|
"authorList":["Arcanitor", "NikkyAi"],
|
||||||
"credits": "Blame Nikky for talking me into this."
|
"credits": "Blame Nikky for talking me into this."
|
||||||
}]
|
}]
|
Loading…
Reference in New Issue