Chat Translator plugin (#824)
* Initial push for Chat Translation Plugin. * Need help adding the 'Translate' menu option for translating selected Players messages. Finished outgoing message translation however if the user has been limited by Google for the likes of using the Public Chat translation in over populated and spammy areas such as the GE they will not be able to send a message for upto 5 minutes while the Player Chat Translation config is enabled. Need to think more about ways to handle this though once the selective translation has been completed we can safely remove the 'All' public chat messages part of the plugin to prevent users from being Limited by Google. * Clean-up for Travis. * Hidden the Public Chat Translation until a better implementation is added to prevent users from being accidentally locked out by Google. * Hidden the Public Chat Translation until a better implementation is added to prevent users from being accidentally locked out by Google. * Added config options for adding the 'Translate' right-click menu option in the Chatbox. (More so to hide it while the Public Chat Translate part of the plugin is disabled/hidden.) * Update ChatTranslationConfig.java
This commit is contained in:
committed by
James
parent
358b8d05d0
commit
69dbeb523d
@@ -284,6 +284,11 @@
|
||||
<artifactId>asm-all</artifactId>
|
||||
<version>6.0_BETA</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20180813</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package net.runelite.client.plugins.chattranslation;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("chattranslation")
|
||||
public interface ChatTranslationConfig extends Config
|
||||
{
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "publicChat",
|
||||
name = "Translate incoming Messages",
|
||||
description = "Would you like to Translate Public Chat?",
|
||||
position = 0,
|
||||
group = "Public Chat Translation",
|
||||
hidden = true
|
||||
)
|
||||
default boolean publicChat()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "translateOptionVisable",
|
||||
name = "Show 'Translate' menu option",
|
||||
description = "Adds 'Translate' to the right-click menu in the Chatbox.",
|
||||
position = 1,
|
||||
group = "Public Chat Translation",
|
||||
hidden = true
|
||||
// unhide = "publicChat"
|
||||
)
|
||||
default boolean translateOptionVisable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "publicTargetLanguage",
|
||||
name = "Target Language",
|
||||
description = "Language to translate messages too.",
|
||||
position = 2,
|
||||
group = "Public Chat Translation",
|
||||
hidden = true
|
||||
// unhide = "publicChat"
|
||||
)
|
||||
default Languages publicTargetLanguage()
|
||||
{
|
||||
return Languages.ENGLISH;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "playerChat",
|
||||
name = "Translate outgoing Messages",
|
||||
description = "Would you like to Translate your Messages?",
|
||||
position = 3,
|
||||
group = "Player Message Translation"
|
||||
)
|
||||
default boolean playerChat()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "playerTargetLanguage",
|
||||
name = "Target Language",
|
||||
description = "Language to translate messages too.",
|
||||
position = 4,
|
||||
group = "Player Message Translation",
|
||||
hidden = true,
|
||||
unhide = "playerChat"
|
||||
)
|
||||
default Languages playerTargetLanguage()
|
||||
{
|
||||
return Languages.SPANISH;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
package net.runelite.client.plugins.chattranslation;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
import com.google.inject.Provides;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.PlayerMenuOptionClicked;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.menus.MenuManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Chat Translator",
|
||||
description = "Translates messages from one Language to another.",
|
||||
tags = {"translate", "language", "english", "spanish", "dutch", "french"},
|
||||
type = PluginType.UTILITY
|
||||
)
|
||||
public class ChatTranslationPlugin extends Plugin implements KeyListener
|
||||
{
|
||||
|
||||
private static final String TRANSLATE = "Translate";
|
||||
private static final ImmutableList<String> AFTER_OPTIONS = ImmutableList.of("Message", "Add ignore", "Remove friend", "Kick");
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private Provider<MenuManager> menuManager;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
@Inject
|
||||
private ChatTranslationConfig config;
|
||||
|
||||
@Provides
|
||||
ChatTranslationConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(ChatTranslationConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
if (client != null)
|
||||
{
|
||||
if (config.translateOptionVisable())
|
||||
{
|
||||
menuManager.get().addPlayerMenuItem(TRANSLATE);
|
||||
}
|
||||
}
|
||||
keyManager.registerKeyListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
if (client != null)
|
||||
{
|
||||
if (config.translateOptionVisable())
|
||||
{
|
||||
menuManager.get().removePlayerMenuItem(TRANSLATE);
|
||||
}
|
||||
}
|
||||
keyManager.unregisterKeyListener(this);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event)
|
||||
{
|
||||
if (event.getMenuOption().equals(TRANSLATE))
|
||||
{
|
||||
//TODO: Translate selected message.
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (!config.translateOptionVisable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int groupId = WidgetInfo.TO_GROUP(event.getActionParam1());
|
||||
String option = event.getOption();
|
||||
|
||||
if (groupId == WidgetInfo.CHATBOX.getGroupId())
|
||||
{
|
||||
boolean after;
|
||||
|
||||
if (!AFTER_OPTIONS.contains(option))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final MenuEntry lookup = new MenuEntry();
|
||||
lookup.setOption(TRANSLATE);
|
||||
lookup.setTarget(event.getTarget());
|
||||
lookup.setType(MenuAction.RUNELITE.getId());
|
||||
lookup.setParam0(event.getActionParam0());
|
||||
lookup.setParam1(event.getActionParam1());
|
||||
lookup.setIdentifier(event.getIdentifier());
|
||||
|
||||
MenuEntry[] newMenu = ObjectArrays.concat(lookup, client.getMenuEntries());
|
||||
int menuEntryCount = newMenu.length;
|
||||
ArrayUtils.swap(newMenu, menuEntryCount - 1, menuEntryCount - 2);
|
||||
client.setMenuEntries(newMenu);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (chatMessage.getType())
|
||||
{
|
||||
case PUBLICCHAT:
|
||||
case MODCHAT:
|
||||
if (!config.publicChat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
String message = chatMessage.getMessage();
|
||||
|
||||
Translator translator = new Translator();
|
||||
|
||||
try
|
||||
{
|
||||
//Automatically check language of message and translate to selected language.
|
||||
String translation = translator.translate("auto", config.publicTargetLanguage().toString(), message);
|
||||
if (translation != null)
|
||||
{
|
||||
final MessageNode messageNode = chatMessage.getMessageNode();
|
||||
messageNode.setRuneLiteFormatMessage(translation);
|
||||
chatMessageManager.update(messageNode);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
client.refreshChat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent event)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.playerChat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT);
|
||||
|
||||
if (chatboxParent != null && chatboxParent.getOnKeyListener() != null)
|
||||
{
|
||||
if (event.getKeyCode() == 0xA)
|
||||
{
|
||||
event.consume();
|
||||
|
||||
Translator translator = new Translator();
|
||||
String message = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT);
|
||||
|
||||
try
|
||||
{
|
||||
//Automatically check language of message and translate to selected language.
|
||||
String translation = translator.translate("auto", config.playerTargetLanguage().toString(), message);
|
||||
if (translation != null)
|
||||
{
|
||||
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, translation);
|
||||
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
client.runScript(96, 0, translation);
|
||||
});
|
||||
}
|
||||
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, "");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
// Nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
// Nothing.
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package net.runelite.client.plugins.chattranslation;
|
||||
|
||||
public enum Languages
|
||||
{
|
||||
|
||||
ENGLISH("en"),
|
||||
DUTCH("nl"),
|
||||
SPANISH("es"),
|
||||
FRENCH("fr");
|
||||
|
||||
private final String shortName;
|
||||
|
||||
Languages(String shortName)
|
||||
{
|
||||
this.shortName = shortName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return shortName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package net.runelite.client.plugins.chattranslation;
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
public class Translator
|
||||
{
|
||||
|
||||
public String translate(String source, String target, String message) throws Exception
|
||||
{
|
||||
|
||||
String url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=" + source + "&tl=" + target + "&dt=t&q=" + URLEncoder.encode(message, "UTF-8");
|
||||
|
||||
URL obj = new URL(url);
|
||||
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
|
||||
con.setRequestProperty("User-Agent", "Mozilla/5.0");
|
||||
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
||||
String inputLine;
|
||||
StringBuffer response = new StringBuffer();
|
||||
|
||||
while ((inputLine = in.readLine()) != null)
|
||||
{
|
||||
response.append(inputLine);
|
||||
}
|
||||
in.close();
|
||||
|
||||
return parseResult(response.toString());
|
||||
}
|
||||
|
||||
private String parseResult(String inputJson) throws Exception
|
||||
{
|
||||
//TODO: find a way to do this using google.gson
|
||||
JSONArray jsonArray = new JSONArray(inputJson);
|
||||
JSONArray jsonArray2 = (JSONArray) jsonArray.get(0);
|
||||
JSONArray jsonArray3 = (JSONArray) jsonArray2.get(0);
|
||||
|
||||
return jsonArray3.get(0).toString();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user