2025-03-11 14:09:49 +01:00
|
|
|
package game.gui;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
2025-03-16 17:40:47 +01:00
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
|
2025-03-11 14:09:49 +01:00
|
|
|
import game.gui.element.ActButton;
|
|
|
|
import game.gui.element.Fill;
|
|
|
|
import game.gui.element.Textbox;
|
|
|
|
import game.gui.element.TransparentBox;
|
|
|
|
import game.gui.element.Textbox.Action;
|
|
|
|
import game.log.Log;
|
|
|
|
import game.network.NetHandlerPlayServer;
|
|
|
|
import game.packet.CPacketComplete;
|
|
|
|
import game.util.ExtMath;
|
|
|
|
import game.window.Keysym;
|
|
|
|
|
|
|
|
public class GuiConsole extends Gui implements Textbox.Callback {
|
|
|
|
public static final GuiConsole INSTANCE = new GuiConsole();
|
|
|
|
|
|
|
|
private final List<String> sentMessages = Lists.<String>newArrayList();
|
|
|
|
|
|
|
|
private String historyBuffer = "";
|
|
|
|
private int sentHistoryCursor = -1;
|
|
|
|
private boolean playerNamesFound;
|
|
|
|
private boolean waitingOnAutocomplete;
|
|
|
|
private int autocompleteIndex;
|
|
|
|
private List<String> foundPlayerNames = Lists.<String>newArrayList();
|
|
|
|
private Textbox inputField;
|
|
|
|
private TransparentBox logBox;
|
|
|
|
|
|
|
|
public void init(int width, int height) {
|
|
|
|
this.addSelector("con_autoclose", 0, 0, 160, 24);
|
|
|
|
this.addSelector("con_timestamps", 160, 0, 160, 24);
|
|
|
|
this.addSelector("con_loglevel", 320, 0, 160, 24);
|
|
|
|
this.add(new ActButton(480, 0, 160, 24, new ActButton.Callback() {
|
|
|
|
public void use(ActButton elem, ActButton.Mode action) {
|
|
|
|
GuiConsole.this.reset();
|
|
|
|
GuiConsole.this.setLog(GuiConsole.this.gm.getBuffer());
|
|
|
|
}
|
|
|
|
}, "Löschen"));
|
|
|
|
this.logBox = this.add(new TransparentBox(0, 24, width, height - 48, this.gm.getBuffer()));
|
|
|
|
this.add(new Fill(640, 0, width - 640, 24));
|
|
|
|
this.inputField = this.add(new Textbox(0, height - 24, width, 24, NetHandlerPlayServer.MAX_CMD_LENGTH, true, this, ""));
|
|
|
|
this.inputField.setSelected();
|
|
|
|
this.sentHistoryCursor = this.sentMessages.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getTitle() {
|
|
|
|
return "Konsole / Chat";
|
|
|
|
}
|
|
|
|
|
|
|
|
public void reset() {
|
|
|
|
this.gm.reset();
|
|
|
|
this.sentMessages.clear();
|
|
|
|
this.sentHistoryCursor = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setLog(String buffer) {
|
|
|
|
if(this.logBox != null)
|
|
|
|
this.logBox.setText(buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void drawMainBackground() {
|
|
|
|
if(this.gm.theWorld == null)
|
|
|
|
super.drawMainBackground();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void key(Keysym key, boolean ctrl, boolean shift) {
|
|
|
|
super.key(key, ctrl, shift);
|
|
|
|
// this.waitingOnAutocomplete = false;
|
|
|
|
if(key != Keysym.TAB)
|
|
|
|
this.playerNamesFound = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void use(Textbox elem, Action value)
|
|
|
|
{
|
|
|
|
this.waitingOnAutocomplete = false;
|
|
|
|
|
|
|
|
if ((value == Action.FORWARD || value == Action.BACKWARD) && this.gm.thePlayer != null)
|
|
|
|
{
|
|
|
|
this.autocompletePlayerNames();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.playerNamesFound = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(value == Action.PREVIOUS)
|
|
|
|
this.getSentHistory(-1);
|
|
|
|
else if (value == Action.NEXT)
|
|
|
|
this.getSentHistory(1);
|
|
|
|
if(value == Action.SEND)
|
|
|
|
{
|
|
|
|
String s = this.inputField.getText().trim();
|
|
|
|
|
|
|
|
if (s.length() > 0)
|
|
|
|
{
|
|
|
|
if(this.sentMessages.isEmpty() || !((String)this.sentMessages.get(this.sentMessages.size() - 1)).equals(s))
|
|
|
|
this.sentMessages.add(s);
|
|
|
|
this.gm.exec(s);
|
|
|
|
// if(this.gm.thePlayer != null)
|
|
|
|
// this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketMessage(CPacketMessage.Type.CHAT, s));
|
|
|
|
}
|
|
|
|
|
|
|
|
this.inputField.setText("");
|
|
|
|
if(this.gm.conAutoclose && this.gm.theWorld != null)
|
|
|
|
this.gm.displayGuiScreen(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void setText(String newChatText, boolean shouldOverwrite)
|
|
|
|
{
|
|
|
|
if (shouldOverwrite)
|
|
|
|
{
|
|
|
|
this.inputField.setText(newChatText);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.inputField.insertText(newChatText);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void autocompletePlayerNames()
|
|
|
|
{
|
|
|
|
if (this.playerNamesFound)
|
|
|
|
{
|
|
|
|
this.inputField.deleteFromCursor();
|
|
|
|
|
|
|
|
if (this.autocompleteIndex >= this.foundPlayerNames.size())
|
|
|
|
{
|
|
|
|
this.autocompleteIndex = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int i = this.inputField.getNthCharFromPos();
|
|
|
|
this.foundPlayerNames.clear();
|
|
|
|
this.autocompleteIndex = 0;
|
|
|
|
String s = this.inputField.getText().substring(i).toLowerCase();
|
|
|
|
String s1 = this.inputField.getText().substring(0, this.inputField.getCursorPosition());
|
|
|
|
this.sendAutocompleteRequest(s1, s);
|
|
|
|
|
|
|
|
if (this.foundPlayerNames.isEmpty())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.playerNamesFound = true;
|
|
|
|
this.inputField.deleteFromCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.foundPlayerNames.size() > 1)
|
|
|
|
{
|
|
|
|
StringBuilder stringbuilder = new StringBuilder();
|
|
|
|
|
|
|
|
for (String s2 : this.foundPlayerNames)
|
|
|
|
{
|
|
|
|
if (stringbuilder.length() > 0)
|
|
|
|
{
|
|
|
|
stringbuilder.append(", ");
|
|
|
|
}
|
|
|
|
|
|
|
|
stringbuilder.append(s2);
|
|
|
|
}
|
|
|
|
|
|
|
|
Log.CONSOLE.user(stringbuilder.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
this.inputField.insertText((String)this.foundPlayerNames.get(this.autocompleteIndex++));
|
|
|
|
}
|
|
|
|
|
|
|
|
private void sendAutocompleteRequest(String currentText, String newText)
|
|
|
|
{
|
|
|
|
if (currentText.length() >= 1)
|
|
|
|
{
|
|
|
|
// BlockPos blockpos = null;
|
|
|
|
// int eid = -1;
|
|
|
|
//
|
|
|
|
// if (this.gm.pointed != null && this.gm.pointed.type == HitPosition.ObjectType.BLOCK)
|
|
|
|
// {
|
|
|
|
// blockpos = this.gm.pointed.block;
|
|
|
|
// }
|
|
|
|
// else if (this.gm.pointed != null && this.gm.pointed.type == HitPosition.ObjectType.ENTITY)
|
|
|
|
// {
|
|
|
|
// eid = this.gm.pointed.entity.getId();
|
|
|
|
// }
|
|
|
|
|
|
|
|
this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketComplete(currentText));
|
|
|
|
this.waitingOnAutocomplete = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void getSentHistory(int msgPos)
|
|
|
|
{
|
|
|
|
int i = this.sentHistoryCursor + msgPos;
|
|
|
|
int j = this.sentMessages.size();
|
|
|
|
i = ExtMath.clampi(i, 0, j);
|
|
|
|
|
|
|
|
if (i != this.sentHistoryCursor)
|
|
|
|
{
|
|
|
|
if (i == j)
|
|
|
|
{
|
|
|
|
this.sentHistoryCursor = j;
|
|
|
|
this.inputField.setText(this.historyBuffer);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (this.sentHistoryCursor == j)
|
|
|
|
{
|
|
|
|
this.historyBuffer = this.inputField.getText();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.inputField.setText(this.sentMessages.get(i));
|
|
|
|
this.sentHistoryCursor = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onAutocompleteResponse(String[] choices)
|
|
|
|
{
|
|
|
|
if (this.waitingOnAutocomplete)
|
|
|
|
{
|
|
|
|
this.playerNamesFound = false;
|
|
|
|
this.foundPlayerNames.clear();
|
|
|
|
|
|
|
|
for (String s : choices)
|
|
|
|
{
|
|
|
|
if (s.length() > 0)
|
|
|
|
{
|
|
|
|
this.foundPlayerNames.add(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String s1 = this.inputField.getText().substring(this.inputField.getNthCharFromPos());
|
|
|
|
String s2 = getCommonPrefix(choices);
|
|
|
|
|
|
|
|
if (s2.length() > 0 && !s1.equalsIgnoreCase(s2))
|
|
|
|
{
|
|
|
|
this.inputField.deleteFromCursor();
|
|
|
|
this.inputField.insertText(s2);
|
|
|
|
}
|
|
|
|
else if (this.foundPlayerNames.size() > 0)
|
|
|
|
{
|
|
|
|
this.playerNamesFound = true;
|
|
|
|
this.autocompletePlayerNames();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static String getCommonPrefix(String[] strs) {
|
|
|
|
if (strs != null && strs.length != 0) {
|
|
|
|
int smallestIndexOfDiff = indexOfDifference(strs);
|
|
|
|
if (smallestIndexOfDiff == -1) {
|
|
|
|
return strs[0] == null ? "" : strs[0];
|
|
|
|
} else {
|
|
|
|
return smallestIndexOfDiff == 0 ? "" : strs[0].substring(0, smallestIndexOfDiff);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static int indexOfDifference(CharSequence[] css) {
|
|
|
|
if (css != null && css.length > 1) {
|
|
|
|
boolean anyStringNull = false;
|
|
|
|
boolean allStringsNull = true;
|
|
|
|
int arrayLen = css.length;
|
|
|
|
int shortestStrLen = Integer.MAX_VALUE;
|
|
|
|
int longestStrLen = 0;
|
|
|
|
|
|
|
|
int firstDiff;
|
|
|
|
for (firstDiff = 0; firstDiff < arrayLen; ++firstDiff) {
|
|
|
|
if (css[firstDiff] == null) {
|
|
|
|
anyStringNull = true;
|
|
|
|
shortestStrLen = 0;
|
|
|
|
} else {
|
|
|
|
allStringsNull = false;
|
|
|
|
shortestStrLen = Math.min(css[firstDiff].length(), shortestStrLen);
|
|
|
|
longestStrLen = Math.max(css[firstDiff].length(), longestStrLen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (allStringsNull || longestStrLen == 0 && !anyStringNull) {
|
|
|
|
return -1;
|
|
|
|
} else if (shortestStrLen == 0) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
firstDiff = -1;
|
|
|
|
|
|
|
|
for (int stringPos = 0; stringPos < shortestStrLen; ++stringPos) {
|
|
|
|
char comparisonChar = css[0].charAt(stringPos);
|
|
|
|
|
|
|
|
for (int arrayPos = 1; arrayPos < arrayLen; ++arrayPos) {
|
|
|
|
if (css[arrayPos].charAt(stringPos) != comparisonChar) {
|
|
|
|
firstDiff = stringPos;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (firstDiff != -1) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return firstDiff == -1 && shortestStrLen != longestStrLen ? shortestStrLen : firstDiff;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|