RuneHive-Game
Loading...
Searching...
No Matches
ChatCodec.java
Go to the documentation of this file.
1package com.runehive.util;
2
3import com.runehive.game.world.entity.mob.player.relations.ChatMessage;
4
5import java.nio.ByteBuffer;
6
7/**
8 * A utility class for encoding/decoding messages.
9 *
10 * @author nshusa
11 */
12public final class ChatCodec {
13
14 /**
15 * The maximum size of an encoded message.
16 */
17 private static final int MAX_COMPRESS_LEN = 80;
18
19 /**
20 * The table that holds all the valid characters that can be used.
21 * These characters are in frequency order. The characters with lower
22 * indexes are used more often.
23 */
24 private static final char[] CHARACTER_TABLE = {
25 ' ', 'e', 't', 'a', 'o', 'i', 'h', 'n', 's', 'r',
26 'd', 'l', 'u', 'm', 'w', 'c', 'y', 'f', 'g', 'p',
27 'b', 'v', 'k', 'x', 'j', 'q', 'z', '0', '1', '2',
28 '3', '4', '5', '6', '7', '8', '9', ' ', '!', '?',
29 '.', ',', ':', ';', '(', ')', '-', '&', '*', '\\',
30 '\'', '@', '#', '+', '=', '\243', '$', '%', '"',
31 '[', ']', '_', '/', '<', '>', '^', '|'
32 };
33
34 /**
35 * Prevent instantiation
36 */
37 private ChatCodec() {
38
39 }
40
41 /**
42 * Encodes an {@code input} string.
43 *
44 * @param input
45 * The input text that will be encoded.
46 *
47 * @return The encoded string.
48 */
49 public static byte[] encode(String input) {
50 if (input.length() > ChatMessage.CHARACTER_LIMIT) {
51 input = input.substring(0, ChatMessage.CHARACTER_LIMIT).toLowerCase();
52 } else {
53 input = input.toLowerCase();
54 }
55
56 ByteBuffer buffer = ByteBuffer.allocate(ChatMessage.CHARACTER_LIMIT);
57
58 int count = 0;
59 for (int i = 0; i < input.length(); i++) {
60 char key = input.charAt(i);
61 int index = 0;
62
63 for (int n = 0; n < CHARACTER_TABLE.length; n++) {
64 if (key != CHARACTER_TABLE[n]) {
65 continue;
66 }
67
68 index = n;
69 count++;
70 break;
71 }
72
73 buffer.put((byte) index);
74 }
75
76 final byte[] temp = new byte[count];
77 System.arraycopy(buffer.array(), 0, temp, 0, temp.length);
78
79 return temp;
80 }
81
82 /**
83 * Decodes an {@code input} string.
84 *
85 * @param input
86 * The string that will be decoded.
87 *
88 * @return The decoded string.
89 */
90 public static String decode(byte[] input) {
91 if (input.length > MAX_COMPRESS_LEN) {
92 byte[] temp = new byte[MAX_COMPRESS_LEN];
93 System.arraycopy(input, 0, temp, 0, temp.length);
94 input = temp;
95 }
96
97 final ByteBuffer buffer = ByteBuffer.wrap(input);
98 final StringBuilder builder = new StringBuilder();
99 for (int i = 0; i < buffer.capacity(); i++) {
100 final int index = buffer.get() & 0xFF;
101 if (index < CHARACTER_TABLE.length) {
102 builder.append(CHARACTER_TABLE[index]);
103 }
104 }
105 return filter(builder.toString());
106 }
107
108 /**
109 * Filters out invalid characters from the {@code input} string and formats the text.
110 *
111 * @code input
112 * The string to filter.
113 *
114 * @return The filtered text.
115 */
116 public static String filter(String input) {
117 final StringBuilder builder = new StringBuilder();
118 for (char c : input.toLowerCase().toCharArray()) {
119 for (char validChar : CHARACTER_TABLE) {
120 if (c == validChar) {
121 builder.append(c);
122 break;
123 }
124 }
125 }
126
127 boolean capitalize = true;
128
129 int length = builder.length();
130
131 for (int index = 0; index < length; index++) {
132 char character = builder.charAt(index);
133
134 if (character == '.' || character == '!' || character == '?') {
135 capitalize = true;
136 } else if (capitalize && !Character.isWhitespace(character)) {
137 builder.setCharAt(index, Character.toUpperCase(character));
138 capitalize = false;
139 } else {
140 builder.setCharAt(index, Character.toLowerCase(character));
141 }
142 }
143
144 return builder.toString();
145 }
146
147}
val index