Created
August 3, 2013 18:46
-
-
Save aadnk/6147547 to your computer and use it in GitHub Desktop.
Transform text into orcish
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.comphenix.example; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
import org.bukkit.ChatColor; | |
import org.bukkit.plugin.java.JavaPlugin; | |
import org.bukkit.event.Listener; | |
import org.json.simple.JSONObject; | |
import org.json.simple.parser.JSONParser; | |
import org.json.simple.parser.ParseException; | |
import com.comphenix.protocol.Packets; | |
import com.comphenix.protocol.ProtocolLibrary; | |
import com.comphenix.protocol.events.ConnectionSide; | |
import com.comphenix.protocol.events.PacketAdapter; | |
import com.comphenix.protocol.events.PacketContainer; | |
import com.comphenix.protocol.events.PacketEvent; | |
public class OrcishMod extends JavaPlugin implements Listener { | |
private Language orcish = new OrcishLanguage(); | |
@Override | |
public void onEnable() { | |
ProtocolLibrary.getProtocolManager().addPacketListener( | |
new PacketAdapter(this, ConnectionSide.SERVER_SIDE, Packets.Server.CHAT) { | |
private JSONParser parser = new JSONParser(); | |
@SuppressWarnings("unchecked") | |
public void onPacketSending(PacketEvent event) { | |
try { | |
PacketContainer packet = event.getPacket(); | |
String json = packet.getStrings().read(0); | |
JSONObject data = (JSONObject) parser.parse(json); | |
String text = (String) data.get("text"); | |
if (text != null) { | |
data.put("text", orcish.translate(text)); | |
// Write back the resulting JSON | |
packet.getStrings().write(0, data.toJSONString()); | |
} | |
} catch (ParseException e) { | |
throw new RuntimeException("Cannot parse JSON.", e); | |
} | |
} | |
} | |
); | |
} | |
private static class Language { | |
// Words sorted by lenght | |
private String[][] words; | |
// Word matcher | |
private Pattern wordPattern = Pattern.compile("(" + ChatColor.COLOR_CHAR + "\\w)*(\\w+)"); | |
public Language(String... words) { | |
@SuppressWarnings("unchecked") | |
List<String>[] bins = (List<String>[]) new List[findLongest(words)]; | |
// Place word into the correct bin | |
for (String word : words) { | |
int i = word.length() - 1; | |
if (bins[i] == null) | |
bins[i] = new ArrayList<String>(); | |
bins[i].add(word); | |
} | |
this.words = generateLookup(bins); | |
} | |
/** | |
* Translate the given text into the current language. | |
* @param text - the text. | |
* @return The resulting language. | |
*/ | |
public String translate(String text) { | |
Matcher matcher = wordPattern.matcher(text); | |
StringBuffer sb = new StringBuffer(); | |
while (matcher.find()) { | |
String translate = translateWord(matcher.group(2)); | |
matcher.appendReplacement(sb, "$1" + Matcher.quoteReplacement(translate)); | |
} | |
matcher.appendTail(sb); | |
return sb.toString(); | |
} | |
/** | |
* Translate a single word. | |
* @param currentWord - the word to translate. | |
* @return The translated word. | |
*/ | |
protected String translateWord(String currentWord) { | |
String[] group = words[Math.min(currentWord.length(), words.length) - 1]; | |
int index = Math.abs(currentWord.hashCode() % group.length); | |
return preserveCase(group[index], currentWord); | |
} | |
protected static String preserveCase(String text, String caseFormat) { | |
char[] modify = text.toCharArray(); | |
char[] template = caseFormat.toCharArray(); | |
// Check every character | |
for (int i = 0; i < modify.length; i++) { | |
if (Character.isLetter(modify[i])) { | |
modify[i] = Character.isUpperCase(template[i]) ? | |
Character.toUpperCase(modify[i]) : Character.toLowerCase(modify[i]); | |
} | |
} | |
return new String(modify); | |
} | |
private static String[][] generateLookup(List<String>[] bins) { | |
String[][] result = new String[bins.length][]; | |
// Generate lookup | |
for (int i = 0; i < bins.length; i++) { | |
result[i] = bins[i].toArray(new String[bins[i].size()]); | |
} | |
return result; | |
} | |
private static int findLongest(String[] words) { | |
int length = 0; | |
for (String word : words) | |
length = Math.max(length, word.length()); | |
return length; | |
} | |
} | |
private static class OrcishLanguage extends Language { | |
public OrcishLanguage() { | |
super( | |
"A", "N", "G", "O", "L", | |
"Ha", "Ko", "No", "Mu", "Ag", "Ka", "Gi", "Il", | |
"Lok", "Tar", "Kaz", "Ruk", "Kek", "Mog", "Zug", "Gul", "Nuk", "Aaz", "Kil", "Ogg", | |
"Rega", "Nogu", "Tago", "Uruk", "Kagg", "Zaga", "Grom", "Ogar", "Gesh", "Thok", "Dogg", "Maka", "Maza", | |
"Regas", "Nogah", "Kazum", "Magan", "No'bu", "Golar", "Throm", "Zugas", "Re'ka", "No'ku", "Ro'th", | |
"Thrakk", "Revash", "Nakazz", "Moguna", "No'gor", "Goth'a", "Raznos", "Ogerin", "Gezzno", "Thukad", "Makogg", "Aaz'no", | |
"Lok'Tar", "Gul'rok", "Kazreth", "Tov'osh", "Zil'Nok", "Rath'is", "Kil'azi", | |
"Throm'ka", "Osh'Kava", "Gul'nath", "Kog'zela", "Ragath'a", "Zuggossh", "Moth'aga", | |
"Tov'nokaz", "Osh'kazil", "No'throma", "Gesh'nuka", "Lok'mogul", "Lok'bolar", "Ruk'ka'ha", | |
"Regasnogah", "Kazum'nobu", "Throm'bola", "Gesh'zugas", "Maza'rotha", "Ogerin'naz", | |
"Thrakk'reva", "Kaz'goth'no", "No'gor'goth", "Kil'azi'aga", "Zug-zug'ama", "Maza'thrakk", | |
"Lokando'nash", "Ul'gammathar", "Golgonnashar", "Dalggo'mazah", | |
"Khaz'rogg'ahn", "Moth'kazoroth"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
regasnogah