From 0487041efae8ef27437b68bdbc8856239ad0eb17 Mon Sep 17 00:00:00 2001 From: hezhenwei Date: Tue, 10 Aug 2021 15:25:34 +0800 Subject: [PATCH] 1. Move the http actions into a new thread to avoid server lagging. --- build.gradle | 2 +- plugin.json | 2 +- src/MykesTool/MTDChatBotPlugin.java | 183 ++++--------------- src/MykesTool/MTDChatEngineThread.java | 236 +++++++++++++++++++++++++ 4 files changed, 271 insertions(+), 152 deletions(-) create mode 100644 src/MykesTool/MTDChatEngineThread.java diff --git a/build.gradle b/build.gradle index d85e6f0..cc26ff6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ apply plugin: "java" -version '0.1.1' +version '0.1.2' sourceCompatibility = 10 diff --git a/plugin.json b/plugin.json index f1cb5ce..6860b3e 100644 --- a/plugin.json +++ b/plugin.json @@ -3,5 +3,5 @@ "author": "Myke.H", "main": "MykesTool.MTDChatBotPlugin", "description": "Mindustry Chat Bot.", - "version": "0.1.1" + "version": "0.1.2" } diff --git a/src/MykesTool/MTDChatBotPlugin.java b/src/MykesTool/MTDChatBotPlugin.java index 57a922d..f333bae 100644 --- a/src/MykesTool/MTDChatBotPlugin.java +++ b/src/MykesTool/MTDChatBotPlugin.java @@ -32,115 +32,6 @@ public class MTDChatBotPlugin extends Plugin{ - - private static String doGet(String httpurl) { - HttpURLConnection connection = null; - InputStream is = null; - BufferedReader br = null; - String result = null;// 返回结果字符串 - try { - // 创建远程url连接对象 - URL url = new URL(httpurl); - // 通过远程url连接对象打开一个连接,强转成httpURLConnection类 - connection = (HttpURLConnection) url.openConnection(); - // 设置连接方式:get - connection.setRequestMethod("GET"); - // 设置连接主机服务器的超时时间:15000毫秒 - connection.setConnectTimeout(15000); - // 设置读取远程返回的数据时间:60000毫秒 - connection.setReadTimeout(60000); - // 发送请求 - connection.connect(); - // 通过connection连接,获取输入流 - if (connection.getResponseCode() == 200) { - is = connection.getInputStream(); - // 封装输入流is,并指定字符集 - br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); - // 存放数据 - StringBuilder sbf = new StringBuilder(); - String temp = null; - while ((temp = br.readLine()) != null) { - sbf.append(temp); - sbf.append("\r\n"); - } - result = sbf.toString(); - } - } catch (MalformedURLException e) { - e.printStackTrace(); - Log.info("try continue"); - } catch (java.net.SocketTimeoutException e){ - e.printStackTrace(); - Log.info("try continue"); - } catch (IOException e) { - e.printStackTrace(); - Log.info("try continue"); - } catch (Exception e) { - e.printStackTrace(); - Log.info("try continue"); - } finally { - // 关闭资源 - if (null != br) { - try { - br.close(); - } catch (IOException e) { - e.printStackTrace(); - Log.info("try continue"); - } catch (Exception e) { - e.printStackTrace(); - Log.info("try continue"); - } - } - - if (null != is) { - try { - is.close(); - } catch (IOException e) { - e.printStackTrace(); - } catch (Exception e) { - e.printStackTrace(); - Log.info("try continue"); - } - } - - if( connection!= null) { - connection.disconnect();// 关闭远程连接 - } - } - - return result; - } - - private String AskAndGetReplyContent(String strAsk) - { - String strEncodedAsk = URLEncoder.encode(strAsk, StandardCharsets.UTF_8); - String strURL = "http://api.qingyunke.com/api.php?key=free&appid=0&msg=" + strEncodedAsk; - String strJsonReply = doGet(strURL); - //Log.info(m_strLogPrefix+strAsk); - //Log.info(m_strLogPrefix+strEncodedAsk); - String strFormattedContent = ""; - - if( m_nDebug == 1) { - Log.info(strJsonReply); - } - //String json = "{\"2\":\"efg\",\"1\":\"abc\"}"; - //JSONObject json_test = JSONObject.fromObject(strReply); - final JSONObject jsonResult = new JSONObject(strJsonReply); - - //Log.info(m_strLogPrefix+jsonResult.getInt("result")); - //Log.info(m_strLogPrefix+jsonResult.getString("content")); - if (0 == jsonResult.getInt("result")) { - //Groups.player.find(); - String strContent = jsonResult.getString("content"); - strFormattedContent = strContent.replace("{br}", "\n"); - - //Time.run(1, () -> player.sendMessage(strMsgPrefix + strFormattedContent)); - //text = text + "\n" + strMsgPrefix + strFormattedContent; - } else { - Log.info(m_strLogPrefix + " error getting message."); - } - return strFormattedContent; - } - private String m_strLogPrefix = "[MykesTool:ChatBot]"; private String m_strBotName = "myke"; private String m_strMsgPrefix = "[red][[[yellow]"+m_strBotName+"的小仆ff[red]]:[white] "; @@ -149,7 +40,23 @@ private String AskAndGetReplyContent(String strAsk) private int m_nDebug = 0; private int m_nLessPeopleActive = 1; private long m_nLastChatTime = 0; - private void DelayReply(Player player, String strMsg) { + private MTDChatEngineThread m_threadEngine = new MTDChatEngineThread(); + + private void GetAndDisplayReply() + { + MTDChatEngineThread.ChatReply chat = m_threadEngine.GetNextReply(); + if( chat != null) + { + if( chat.nHideReply == 0) { + Call.sendMessage(m_strMsgPrefix + chat.strReply); // say to all + } + Log.info(m_strMsgPrefix + chat.strReply); // log this so we can trace back + + m_nLastChatTime = System.currentTimeMillis(); + } + } + + private void AskAsync(Player player, String strMsg) { try { int nBotNamePos = -1; @@ -160,36 +67,22 @@ private void DelayReply(Player player, String strMsg) { //Log.info(nBotNamePos); if (nBotNamePos == 0) { String strAsk = strMsg.substring(strCallName.length()); - String strFormattedReply = AskAndGetReplyContent(strAsk); - Call.sendMessage(m_strMsgPrefix + strFormattedReply); // say to all - Log.info(m_strMsgPrefix + strFormattedReply); // log this so we can trace back - - m_nLastChatTime = System.currentTimeMillis(); + m_threadEngine.AskAsync(player, strAsk, 0); } // if has "@myke" prefix else if (Groups.player.size() <= m_nLessPeopleActive) { String strAsk = strMsg; - String strFormattedReply = AskAndGetReplyContent(strAsk); - Call.sendMessage(m_strMsgPrefix + strFormattedReply); // say to all - Log.info(m_strMsgPrefix + strFormattedReply); // log this so we can trace back - m_nLastChatTime = System.currentTimeMillis(); + m_threadEngine.AskAsync(player, strAsk, 0); } else if (0 == strMsg.indexOf("无聊") || 0 == strMsg.indexOf("有点无聊") || 0 == strMsg.indexOf("好无聊")) { String strAsk = strMsg; - String strFormattedReply = AskAndGetReplyContent(strAsk); - Call.sendMessage(m_strMsgPrefix + strFormattedReply); // say to all - Log.info(m_strMsgPrefix + strFormattedReply); // log this so we can trace back - m_nLastChatTime = System.currentTimeMillis(); + m_threadEngine.AskAsync(player, strAsk, 0); } else { // otherwise, only see what he will reply, but not show them. String strAsk = strMsg; - String strFormattedReply = AskAndGetReplyContent(strAsk); - //Call.sendMessage(m_strMsgPrefix + strFormattedReply); // say to all - Log.info(m_strMsgPrefix + strFormattedReply); // log this so we can trace back - - //m_nLastChatTime = System.currentTimeMillis( ); - + m_threadEngine.AskAsync(player, strAsk, 1); } + Time.runTask(5*60f, () -> GetAndDisplayReply()); }catch ( Exception e) { e.printStackTrace(); @@ -204,18 +97,19 @@ private void StartChat(Player player) int nStartMsg = Mathf.random(m_ArrayPossibleStart.length -1); String strStartMsg = m_ArrayPossibleStart[nStartMsg]; Call.sendMessage(m_strMsgPrefix + "一个人的话,可以和机器人对话:"+strStartMsg); // say to all - DelayReply(player, strStartMsg); + AskAsync(player, strStartMsg); } //called when game initializes @Override public void init() { - //add a chat filter that changes the contents of all messages //in this case, all instances of "heck" are censored Vars.netServer.admins.addChatFilter((player, text) -> { + // if has some reply messages, show them. + GetAndDisplayReply(); /* if(m_playerNew == null || m_nc == null) { m_playerNew = Player.create(); @@ -233,7 +127,7 @@ public void init() { player.sendMessage("test", m_playerNew); */ - Time.run(0, () -> DelayReply(player,text)); + AskAsync(player,text); //player.sendMessage("try to do something for v008"); return text; @@ -249,7 +143,7 @@ public void init() { { // not * 60 is 1 sec // if has very few people, say hi hiddenly - Time.run(Mathf.random(10) * 60f, () -> DelayReply(event.player, "hi")); + AskAsync(event.player, "hi"); } }); @@ -265,28 +159,17 @@ public void init() { // not * 60 is 1 sec int nPlayer = Mathf.random(Groups.player.size()-1); Player player = Groups.player.index(nPlayer); - Time.run(Mathf.random(10) * 60f, () -> StartChat(player)); + StartChat(player); } }); - /* - Vars.netServer.admins.addActionFilter(action -> { - - // when user do any action - long nNow = System.currentTimeMillis( ); - long nDiff = nNow - m_nLastChatTime; - //Log.info("ndeiff." + nDiff); - if( nDiff > (120+Mathf.random(480)) * 1000) - { - if( Groups.player.size() <= m_nLessPeopleActive && Groups.player.size() > 0) { - m_nLastChatTime = System.currentTimeMillis( ); - Time.run(Mathf.random(10) * 60f, () -> StartChat(action.player)); - } - } + Vars.netServer.admins.addActionFilter(action -> { + // get and show it anytime. + // seems it make the server slow. + // GetAndDisplayReply(); return true; }); - */ } @@ -337,4 +220,4 @@ public void registerServerCommands(CommandHandler handler){ }); } -} +} \ No newline at end of file diff --git a/src/MykesTool/MTDChatEngineThread.java b/src/MykesTool/MTDChatEngineThread.java new file mode 100644 index 0000000..3e87f2f --- /dev/null +++ b/src/MykesTool/MTDChatEngineThread.java @@ -0,0 +1,236 @@ +package MykesTool; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import arc.util.Log; +import mindustry.gen.*; +import mindustry.*; +import org.json.JSONObject; + +public class MTDChatEngineThread extends Thread{ + + private static String doGet(String httpurl) { + HttpURLConnection connection = null; + InputStream is = null; + BufferedReader br = null; + String result = null;// 返回结果字符串 + try { + // 创建远程url连接对象 + URL url = new URL(httpurl); + // 通过远程url连接对象打开一个连接,强转成httpURLConnection类 + connection = (HttpURLConnection) url.openConnection(); + // 设置连接方式:get + connection.setRequestMethod("GET"); + // 设置连接主机服务器的超时时间:15000毫秒 + connection.setConnectTimeout(15000); + // 设置读取远程返回的数据时间:60000毫秒 + connection.setReadTimeout(60000); + // 发送请求 + connection.connect(); + // 通过connection连接,获取输入流 + if (connection.getResponseCode() == 200) { + is = connection.getInputStream(); + // 封装输入流is,并指定字符集 + br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); + // 存放数据 + StringBuilder sbf = new StringBuilder(); + String temp = null; + while ((temp = br.readLine()) != null) { + sbf.append(temp); + sbf.append("\r\n"); + } + result = sbf.toString(); + } + } catch (MalformedURLException e) { + e.printStackTrace(); + Log.info("try continue"); + } catch (java.net.SocketTimeoutException e){ + e.printStackTrace(); + Log.info("try continue"); + } catch (IOException e) { + e.printStackTrace(); + Log.info("try continue"); + } catch (Exception e) { + e.printStackTrace(); + Log.info("try continue"); + } finally { + // 关闭资源 + if (null != br) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + Log.info("try continue"); + } catch (Exception e) { + e.printStackTrace(); + Log.info("try continue"); + } + } + + if (null != is) { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + Log.info("try continue"); + } + } + + if( connection!= null) { + connection.disconnect();// 关闭远程连接 + } + } + + return result; + } + + public int m_nDebug = 1; + public int m_nRunning = 0; + private String m_strLogPrefix = "[ChatEngineThread]"; + private int i = 10; + private Object object = new Object(); + public class ChatReply { + public Player player; + public String strAsk; + public String strReply; + public int nHideReply; + public ChatReply(Player player, String strAsk) + { + this.player = player; + this.strAsk = strAsk; + this.strReply =""; + nHideReply = 0; + } + } + private ArrayList m_ListAsk = new ArrayList() ; + private ArrayList m_ListReply = new ArrayList() ; + + public MTDChatEngineThread() + { + Log.info("Start MTDChatEngine Thread"); + m_nRunning = 1; + this.start(); + } + + // note this may be called in another thread. + public void AskAsync(Player player, String strAsk, int nHideReply) + { + ChatReply chat = new ChatReply(player, strAsk); + chat.nHideReply = nHideReply; + synchronized (m_ListAsk) { + m_ListAsk.add(chat); + } + if( m_nDebug == 1) { + Log.info("Insert chat:"+player.toString()+":"+strAsk); + } + // if it's stopped because of server stop, restart it. + if(m_nRunning == 0) + { + m_nRunning =1; + this.start(); + } + } + + // note this may be called in another thread. + public ChatReply GetNextReply() + { + ChatReply chat = null; + Log.info("trying to get reply:"); + synchronized (m_ListReply) { + // find the one that has not get replied. + for (ChatReply chatOne:m_ListReply) { + Log.info("itering reply:"+chatOne.strReply); + if( "" != chatOne.strReply) { + chat = chatOne; + Log.info("find reply:"+chatOne.strReply); + m_ListReply.remove(chatOne); + break; + } + } + + } + return chat; + + } + + @Override + public void run() { + m_nRunning = 1; + ChatReply chat ; + while (1 == m_nRunning) { + //Log.info("Running MTDChatEngine Thread"); + + chat = null; + synchronized (m_ListAsk) { + // find the one that has not get replied. + for (ChatReply chatOne:m_ListAsk) { + if( "" == chatOne.strReply) { + chat = chatOne; + m_ListAsk.remove(chatOne); + break; + } + } + } + + // get the content through http + if( chat != null) { + String strEncodedAsk = URLEncoder.encode(chat.strAsk, StandardCharsets.UTF_8); + String strURL = "http://api.qingyunke.com/api.php?key=free&appid=0&msg=" + strEncodedAsk; + String strJsonReply = doGet(strURL); + //Log.info(m_strLogPrefix+strAsk); + //Log.info(m_strLogPrefix+strEncodedAsk); + String strFormattedContent = ""; + + if (m_nDebug == 1) { + Log.info(strJsonReply); + } + //String json = "{\"2\":\"efg\",\"1\":\"abc\"}"; + //JSONObject json_test = JSONObject.fromObject(strReply); + final JSONObject jsonResult = new JSONObject(strJsonReply); + + //Log.info(m_strLogPrefix+jsonResult.getInt("result")); + //Log.info(m_strLogPrefix+jsonResult.getString("content")); + if (0 == jsonResult.getInt("result")) { + //Groups.player.find(); + String strContent = jsonResult.getString("content"); + strFormattedContent = strContent.replace("{br}", "\n"); + + //Time.run(1, () -> player.sendMessage(strMsgPrefix + strFormattedContent)); + //text = text + "\n" + strMsgPrefix + strFormattedContent; + } else { + Log.info(m_strLogPrefix + " error getting message."); + } + chat.strReply = strFormattedContent; + Log.info("adding chat reply "+chat); + synchronized (m_ListReply) { + Log.info("adding chat reply2 "+chat); + m_ListReply.add(chat); + } + } + + try { + Thread.currentThread().sleep(3000); + } catch (InterruptedException e) { + // TODO: handle exception + } + if( !Vars.net.active()) + { + Log.info("Stop MTDChatEngine Thread"); + System.out.println("Stop MTDChatEngine Thread"); + break; + } + } + } +}