Update gaming network UI with option to choose channel

This commit is contained in:
Retera 2022-03-08 09:35:28 -05:00
parent 9becca479e
commit c6bb695b2c
14 changed files with 204 additions and 45 deletions

View File

@ -28,6 +28,7 @@ import com.etheller.warsmash.networking.uberserver.GamingNetworkConnectionImpl;
import com.etheller.warsmash.parsers.fdf.GameUI;
import com.etheller.warsmash.parsers.jass.Jass2.RootFrameListener;
import com.etheller.warsmash.units.DataTable;
import com.etheller.warsmash.units.Element;
import com.etheller.warsmash.util.ImageUtils;
import com.etheller.warsmash.util.StringBundle;
import com.etheller.warsmash.util.WarsmashConstants;
@ -192,6 +193,14 @@ public class WarsmashGdxMenuScreen implements InputProcessor, Screen, SingleMode
}
}
String server;
final Element gamingNetworkSettings = this.warsmashIni.get("GamingNetwork");
if (gamingNetworkSettings != null) {
server = gamingNetworkSettings.getField("Server");
}
else {
server = "localhost";
}
this.menuUI = new MenuUI(this.viewer.dataSource, this.uiViewport, this.uiScene, this.viewer, this.game,
this, this.warsmashIni, new RootFrameListener() {
@Override
@ -211,7 +220,7 @@ public class WarsmashGdxMenuScreen implements InputProcessor, Screen, SingleMode
WarsmashGdxMenuScreen.this.mainInstance.setScene(WarsmashGdxMenuScreen.this.uiScene);
}
}
}, new GamingNetworkConnectionImpl("localhost"));
}, new GamingNetworkConnectionImpl(server));
final ModelInstance libgdxContentInstance = new LibGDXContentLayerModel(null, this.viewer, "",
PathSolver.DEFAULT, "").addInstance();

View File

@ -29,7 +29,7 @@ public class GamingNetworkConnectionImpl implements GamingNetworkConnection {
public void start() {
this.tcpChannel = this.selectableChannelOpener.openTCPClientChannel(
new InetSocketAddress("localhost", GamingNetwork.PORT),
new InetSocketAddress(this.gateway, GamingNetwork.PORT),
new TCPGamingNetworkServerToClientParser(this.notifier), ExceptionListener.THROW_RUNTIME,
8 * 1024 * 1024, ByteOrder.LITTLE_ENDIAN);
this.gamingNetworkClientToServerWriter = new GamingNetworkClientToServerWriter(this.tcpChannel);

View File

@ -1029,7 +1029,7 @@ public final class GameUI extends AbstractUIFrame implements UIFrame {
}
inflatedFrame = controlFrame;
}
else if (false && "TEXTAREA".equals(frameDefinition.getFrameType())) {
else if ("TEXTAREA".equals(frameDefinition.getFrameType())) {
// TODO advanced components here
final TextAreaFrame controlFrame = new TextAreaFrame(frameDefinition.getName(), parent, viewport2);
// TODO: we should not need to put ourselves in this map 2x, but we do

View File

@ -1,5 +1,6 @@
package com.etheller.warsmash.parsers.fdf.frames;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
@ -123,6 +124,15 @@ public class EditBoxFrame extends AbstractRenderableFrame implements FocusableFr
}
break;
}
case Input.Keys.V: {
if (Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT) || Gdx.input.isKeyPressed(Input.Keys.CONTROL_RIGHT)) {
final String contents = Gdx.app.getClipboard().getContents();
for (int i = 0; i < contents.length(); i++) {
keyTyped(contents.charAt(i));
}
}
break;
}
}
return false;
}

View File

@ -109,8 +109,13 @@ public class ScrollBarFrame extends AbstractRenderableFrame implements Clickable
public void updateThumbButtonPoint() {
final float newYValue = (this.scrollValuePercent / 100f) * getMaxThumbButtonTravelDistance();
this.thumbButtonFrame
.addSetPoint(new SetPoint(FramePoint.BOTTOM, this.decButtonFrame, FramePoint.TOP, 0, newYValue));
if (this.decButtonFrame != null) {
this.thumbButtonFrame
.addSetPoint(new SetPoint(FramePoint.BOTTOM, this.decButtonFrame, FramePoint.TOP, 0, newYValue));
}
else {
this.thumbButtonFrame.addSetPoint(new SetPoint(FramePoint.BOTTOM, this, FramePoint.BOTTOM, 0, newYValue));
}
}
@Override

View File

@ -42,6 +42,9 @@ public class SetPoint implements FramePointAssignment {
@Override
public float getX(final GameUI gameUI, final Viewport uiViewport) {
if (this.other == null) {
throw new NullPointerException();
}
return this.other.getFramePointX(this.otherPoint) + this.x;
}

View File

@ -274,28 +274,37 @@ public class MenuUI {
@Override
public void loginFailed(final LoginFailureReason loginFailureReason) {
String msg;
switch (loginFailureReason) {
case INVALID_CREDENTIALS:
msg = "ERROR_ID_BADPASSWORD";
break;
case UNKNOWN_USER:
msg = "ERROR_ID_UNKNOWNACCOUNT";
break;
default:
msg = "ERROR_ID_INVALIDPARAMS";
break;
}
MenuUI.this.dialog.showError(msg, null);
Gdx.app.postRunnable(new Runnable() {
@Override
public void run() {
String msg;
switch (loginFailureReason) {
case INVALID_CREDENTIALS:
msg = "ERROR_ID_BADPASSWORD";
break;
case UNKNOWN_USER:
msg = "ERROR_ID_UNKNOWNACCOUNT";
break;
default:
msg = "ERROR_ID_INVALIDPARAMS";
break;
}
MenuUI.this.dialog.showError(msg, null);
}
});
}
@Override
public void joinedChannel(final String channelName) {
MenuUI.this.battleNetUI.joinedChannel(channelName);
MenuUI.this.battleNetUI.hideWelcomeScreen();
MenuUI.this.glueSpriteLayerTopLeft.setSequence("BattleNetWelcome Death");
MenuUI.this.glueSpriteLayerTopRight.setSequence("BattleNetWelcome Death");
MenuUI.this.menuState = MenuState.GOING_TO_BATTLE_NET_CHAT_CHANNEL;
Gdx.app.postRunnable(new Runnable() {
@Override
public void run() {
MenuUI.this.battleNetUI.joinedChannel(channelName);
MenuUI.this.battleNetUI.hideCurrentScreen();
playCurrentBattleNetGlueSpriteDeath();
MenuUI.this.menuState = MenuState.GOING_TO_BATTLE_NET_CHAT_CHANNEL;
}
});
}
@Override
@ -327,17 +336,32 @@ public class MenuUI {
@Override
public void channelMessage(final String userName, final String message) {
MenuUI.this.battleNetUI.channelMessage(userName, message);
Gdx.app.postRunnable(new Runnable() {
@Override
public void run() {
MenuUI.this.battleNetUI.channelMessage(userName, message);
}
});
}
@Override
public void channelEmote(final String userName, final String message) {
MenuUI.this.battleNetUI.channelEmote(userName, message);
Gdx.app.postRunnable(new Runnable() {
@Override
public void run() {
MenuUI.this.battleNetUI.channelEmote(userName, message);
}
});
}
@Override
public void badSession() {
MenuUI.this.dialog.showError("ERROR_ID_NOTLOGGEDON", null);
Gdx.app.postRunnable(new Runnable() {
@Override
public void run() {
MenuUI.this.dialog.showError("ERROR_ID_NOTLOGGEDON", null);
}
});
}
@Override
@ -1016,6 +1040,19 @@ public class MenuUI {
"Frozen Throne USA-1"); // TODO maybe not hardcode this
}
@Override
public void returnToChat() {
MenuUI.this.battleNetUI.hideCurrentScreen();
playCurrentBattleNetGlueSpriteDeath();
MenuUI.this.menuState = MenuState.GOING_TO_BATTLE_NET_CHAT_CHANNEL;
}
@Override
public void requestJoinChannel(final String text) {
MenuUI.this.gamingNetworkConnection.joinChannel(MenuUI.this.battleNetUI.getGamingNetworkSessionToken(),
text);
}
@Override
public void createAccount(final String username, final String password, final String repeatPassword) {
if (!password.equals(repeatPassword)) {
@ -1051,6 +1088,14 @@ public class MenuUI {
.chatMessage(MenuUI.this.battleNetUI.getGamingNetworkSessionToken(), text);
}
}
@Override
public void showChannelChooserPanel() {
MenuUI.this.battleNetUI.hideCurrentScreen();
playCurrentBattleNetGlueSpriteDeath();
MenuUI.this.menuState = MenuState.GOING_TO_BATTLE_NET_CHANNEL_MENU;
}
});
this.dialog = new DialogWar3(this.rootFrame, this.uiViewport);
@ -1293,6 +1338,17 @@ public class MenuUI {
}
return;
}
if (this.currentMusics != null) {
if (!this.currentMusics[this.currentMusicIndex].isPlaying()) {
if (this.currentMusicRandomizeIndex) {
this.currentMusicIndex = (int) (Math.random() * this.currentMusics.length);
}
else {
this.currentMusicIndex = (this.currentMusicIndex + 1) % this.currentMusics.length;
}
this.currentMusics[this.currentMusicIndex].play();
}
}
if ((this.focusUIFrame != null) && !this.focusUIFrame.isVisibleOnScreen()) {
setFocusFrame(getNextFocusFrame());
}
@ -1387,6 +1443,16 @@ public class MenuUI {
MenuUI.this.glueSpriteLayerTopLeft.setSequence("BattleNetCustom Stand");
MenuUI.this.glueSpriteLayerTopRight.setSequence("BattleNetCustom Stand");
break;
case GOING_TO_BATTLE_NET_CHANNEL_MENU:
MenuUI.this.glueSpriteLayerTopLeft.setSequence("BattleNetChannel Birth");
MenuUI.this.glueSpriteLayerTopRight.setSequence("BattleNetChannel Birth");
this.menuState = MenuState.BATTLE_NET_CHANNEL_MENU;
break;
case BATTLE_NET_CHANNEL_MENU:
this.battleNetUI.showChannelMenu();
MenuUI.this.glueSpriteLayerTopLeft.setSequence("BattleNetChannel Stand");
MenuUI.this.glueSpriteLayerTopRight.setSequence("BattleNetChannel Stand");
break;
case GOING_TO_BATTLE_NET_CHAT_CHANNEL:
MenuUI.this.glueSpriteLayerTopLeft.setSequence("BattleNetChatRoom Birth");
MenuUI.this.glueSpriteLayerTopRight.setSequence("BattleNetChatRoom Birth");
@ -1622,11 +1688,12 @@ public class MenuUI {
private static enum MenuState {
GOING_TO_MAIN_MENU, MAIN_MENU, GOING_TO_BATTLE_NET_LOGIN, GOING_TO_BATTLE_NET_LOGIN_PART2, BATTLE_NET_LOGIN,
LEAVING_BATTLE_NET, LEAVING_BATTLE_NET_FROM_LOGGED_IN, GOING_TO_BATTLE_NET_CUSTOM_GAME_MENU,
BATTLE_NET_CUSTOM_GAME_MENU, GOING_TO_BATTLE_NET_WELCOME, BATTLE_NET_WELCOME, GOING_TO_SINGLE_PLAYER,
LEAVING_CAMPAIGN, SINGLE_PLAYER, GOING_TO_SINGLE_PLAYER_SKIRMISH, SINGLE_PLAYER_SKIRMISH, GOING_TO_MAP,
GOING_TO_CAMPAIGN, GOING_TO_CAMPAIGN_PART2, GOING_TO_MISSION_SELECT, MISSION_SELECT, CAMPAIGN,
GOING_TO_SINGLE_PLAYER_PROFILE, SINGLE_PLAYER_PROFILE, GOING_TO_LOADING_SCREEN, QUITTING, RESTARTING,
GOING_TO_BATTLE_NET_CHAT_CHANNEL, BATTLE_NET_CHAT_CHANNEL;
BATTLE_NET_CUSTOM_GAME_MENU, GOING_TO_BATTLE_NET_CHANNEL_MENU, BATTLE_NET_CHANNEL_MENU,
GOING_TO_BATTLE_NET_WELCOME, BATTLE_NET_WELCOME, GOING_TO_SINGLE_PLAYER, LEAVING_CAMPAIGN, SINGLE_PLAYER,
GOING_TO_SINGLE_PLAYER_SKIRMISH, SINGLE_PLAYER_SKIRMISH, GOING_TO_MAP, GOING_TO_CAMPAIGN,
GOING_TO_CAMPAIGN_PART2, GOING_TO_MISSION_SELECT, MISSION_SELECT, CAMPAIGN, GOING_TO_SINGLE_PLAYER_PROFILE,
SINGLE_PLAYER_PROFILE, GOING_TO_LOADING_SCREEN, QUITTING, RESTARTING, GOING_TO_BATTLE_NET_CHAT_CHANNEL,
BATTLE_NET_CHAT_CHANNEL;
}
public void hide() {
@ -1799,6 +1866,11 @@ public class MenuUI {
MenuUI.this.glueSpriteLayerTopLeft.setSequence("BattleNetChatRoom Death");
MenuUI.this.glueSpriteLayerTopRight.setSequence("BattleNetChatRoom Death");
break;
case BATTLE_NET_CHANNEL_MENU:
case GOING_TO_BATTLE_NET_CHANNEL_MENU:
MenuUI.this.glueSpriteLayerTopLeft.setSequence("BattleNetChannel Death");
MenuUI.this.glueSpriteLayerTopRight.setSequence("BattleNetChannel Death");
break;
default:
case BATTLE_NET_WELCOME:
case GOING_TO_BATTLE_NET_WELCOME:

View File

@ -10,6 +10,7 @@ import com.etheller.warsmash.parsers.fdf.GameUI;
import com.etheller.warsmash.parsers.fdf.frames.BackdropFrame;
import com.etheller.warsmash.parsers.fdf.frames.EditBoxFrame;
import com.etheller.warsmash.parsers.fdf.frames.GlueButtonFrame;
import com.etheller.warsmash.parsers.fdf.frames.GlueTextButtonFrame;
import com.etheller.warsmash.parsers.fdf.frames.SimpleFrame;
import com.etheller.warsmash.parsers.fdf.frames.SpriteFrame;
import com.etheller.warsmash.parsers.fdf.frames.StringFrame;
@ -76,6 +77,10 @@ public class BattleNetUI {
private final GlueButtonFrame okButton;
private final StringFrame chatChannelNameLabel;
private final TextAreaFrame chatTextArea;
private final GlueTextButtonFrame chatChannelButton;
private final GlueButtonFrame channelPanelBackButton;
private final EditBoxFrame channelNameField;
private final GlueButtonFrame channelPanelJoinChannelButton;
public BattleNetUI(final GameUI rootFrame, final Viewport uiViewport,
final BattleNetUIActionListener actionListener) {
@ -245,6 +250,13 @@ public class BattleNetUI {
this.chatPanel = rootFrame.getFrameByName("ChatPanel", 0);
this.chatPanel.setVisible(false);
this.chatChannelNameLabel = (StringFrame) rootFrame.getFrameByName("ChatChannelNameLabel", 0);
this.chatChannelButton = (GlueTextButtonFrame) rootFrame.getFrameByName("ChatChannelButton", 0);
this.chatChannelButton.setOnClick(new Runnable() {
@Override
public void run() {
actionListener.showChannelChooserPanel();
}
});
this.chatTextArea = (TextAreaFrame) rootFrame.getFrameByName("ChatTextArea", 0);
final EditBoxFrame chatEditBox = (EditBoxFrame) rootFrame.getFrameByName("BattleNetChatEditBox", 0);
chatEditBox.setFilterAllowAny();
@ -264,6 +276,24 @@ public class BattleNetUI {
this.channelPanel = rootFrame.getFrameByName("ChannelPanel", 0);
this.channelPanel.setVisible(false);
this.channelPanelBackButton = (GlueButtonFrame) rootFrame.getFrameByName("BackButton", 0);
this.channelPanelBackButton.setOnClick(new Runnable() {
@Override
public void run() {
actionListener.returnToChat();
}
});
this.channelNameField = (EditBoxFrame) rootFrame.getFrameByName("ChannelNameField", 0);
this.channelPanelJoinChannelButton = (GlueButtonFrame) rootFrame.getFrameByName("JoinChannelButton", 0);
final Runnable onJoinChannelClick = new Runnable() {
@Override
public void run() {
actionListener.requestJoinChannel(BattleNetUI.this.channelNameField.getText());
}
};
this.channelNameField.setOnEnter(onJoinChannelClick);
this.channelPanelJoinChannelButton.setOnClick(onJoinChannelClick);
// ********************************
// * The welcome panel
// ********************************
@ -367,6 +397,7 @@ public class BattleNetUI {
public void hideCurrentScreen() {
this.welcomePanel.setVisible(false);
this.chatPanel.setVisible(false);
this.channelPanel.setVisible(false);
this.welcomePanel.setVisible(false);
this.quitBattleNetButton.setVisible(false);
setTopButtonsVisible(false);
@ -401,6 +432,9 @@ public class BattleNetUI {
public void joinedChannel(final String channelName) {
this.rootFrame.setText(this.chatChannelNameLabel, channelName);
final String messageText = String.format(this.rootFrame.getTemplates().getDecoratedString("BNET_JOIN_CHANNEL"),
channelName);
this.chatTextArea.addItem(messageText, this.rootFrame, this.uiViewport);
}
public void channelMessage(final String userName, final String message) {
@ -415,4 +449,8 @@ public class BattleNetUI {
this.rootFrame.getTemplates().getDecoratedString("CHATCOLOR_EMOTE_MESSAGE"), userName, message);
this.chatTextArea.addItem(messageText, this.rootFrame, this.uiViewport);
}
public void showChannelMenu() {
this.channelPanel.setVisible(true);
}
}

View File

@ -16,4 +16,10 @@ public interface BattleNetUIActionListener {
void createAccount(String username, String password, String repeatPassword);
void submitChatText(String text);
void showChannelChooserPanel();
void returnToChat();
void requestJoinChannel(String text);
}

View File

@ -1,13 +1,23 @@
plugins {
id 'org.beryx.runtime' version '1.12.5'
}
sourceSets.main.java.srcDirs = [ "src/" ]
sourceSets.main.resources.srcDirs = [ "src/" ]
project.ext.mainClassName = "com.etheller.warsmash.networking.WarsmashServer"
task run(dependsOn: classes, type: JavaExec) {
main = project.mainClassName
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
ignoreExitValue = true
if(project.hasProperty("args")) {
ext.cmdargs = project.getProperty("args")
} else {
ext.cmdargs = ""
}
application {
mainClass = project.ext.mainClassName
applicationName = 'warsmashgn'
applicationDefaultJvmArgs = []
}
task dist(type: Jar) {

View File

@ -1,5 +1,7 @@
package com.etheller.warsmash.networking.uberserver;
import java.nio.charset.Charset;
import net.warsmash.networking.util.AbstractWriter;
import net.warsmash.nio.channels.WritableOutput;
import net.warsmash.uberserver.AccountCreationFailureReason;
@ -66,7 +68,7 @@ public class GamingNetworkServerToClientWriter extends AbstractWriter implements
if (channelName.length() > GamingNetwork.CHANNEL_NAME_MAX_LENGTH) {
channelName = channelName.substring(0, GamingNetwork.CHANNEL_NAME_MAX_LENGTH);
}
final byte[] bytes = channelName.getBytes();
final byte[] bytes = channelName.getBytes(Charset.forName("utf-8"));
beginMessage(Protocol.JOINED_CHANNEL, 4 + bytes.length);
this.writeBuffer.putInt(bytes.length);
this.writeBuffer.put(bytes);
@ -88,7 +90,7 @@ public class GamingNetworkServerToClientWriter extends AbstractWriter implements
message = message.substring(0, GamingNetwork.MESSAGE_MAX_LENGTH);
}
final byte[] userNameBytes = userName.getBytes();
final byte[] messageBytes = message.getBytes();
final byte[] messageBytes = message.getBytes(Charset.forName("utf-8"));
beginMessage(Protocol.CHANNEL_MESSAGE, 4 + userNameBytes.length + 4 + messageBytes.length);
this.writeBuffer.putInt(userNameBytes.length);
this.writeBuffer.put(userNameBytes);
@ -106,7 +108,7 @@ public class GamingNetworkServerToClientWriter extends AbstractWriter implements
message = message.substring(0, GamingNetwork.MESSAGE_MAX_LENGTH);
}
final byte[] userNameBytes = userName.getBytes();
final byte[] messageBytes = message.getBytes();
final byte[] messageBytes = message.getBytes(Charset.forName("utf-8"));
beginMessage(Protocol.CHANNEL_EMOTE, 4 + userNameBytes.length + 4 + messageBytes.length);
this.writeBuffer.putInt(userNameBytes.length);
this.writeBuffer.put(userNameBytes);

View File

@ -1,6 +1,7 @@
package com.etheller.warsmash.networking.uberserver;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import com.etheller.warsmash.util.War3ID;
@ -71,7 +72,7 @@ public class TCPGamingNetworkServerClientParser implements TCPClientParser {
final int usernameStringLength = Math.min(maxLength, data.getInt());
final byte[] usernameStringBytes = new byte[usernameStringLength];
data.get(usernameStringBytes);
final String username = new String(usernameStringBytes);
final String username = new String(usernameStringBytes, Charset.forName("utf-8"));
return username;
}

View File

@ -1,5 +1,7 @@
package net.warsmash.uberserver;
import java.nio.charset.Charset;
import com.etheller.warsmash.util.War3ID;
import net.warsmash.networking.util.AbstractWriter;
@ -42,7 +44,7 @@ public class GamingNetworkClientToServerWriter extends AbstractWriter implements
if (channelName.length() > GamingNetwork.CHANNEL_NAME_MAX_LENGTH) {
channelName = channelName.substring(0, GamingNetwork.CHANNEL_NAME_MAX_LENGTH);
}
final byte[] channelNameBytes = channelName.getBytes();
final byte[] channelNameBytes = channelName.getBytes(Charset.forName("utf-8"));
beginMessage(Protocol.JOIN_CHANNEL, 8 + 4 + channelNameBytes.length);
this.writeBuffer.putLong(sessionToken);
this.writeBuffer.putInt(channelNameBytes.length);
@ -55,7 +57,7 @@ public class GamingNetworkClientToServerWriter extends AbstractWriter implements
if (text.length() > GamingNetwork.MESSAGE_MAX_LENGTH) {
text = text.substring(0, GamingNetwork.MESSAGE_MAX_LENGTH);
}
final byte[] bytes = text.getBytes();
final byte[] bytes = text.getBytes(Charset.forName("utf-8"));
beginMessage(Protocol.EMOTE_MESSAGE, 8 + 4 + bytes.length);
this.writeBuffer.putLong(sessionToken);
this.writeBuffer.putInt(bytes.length);
@ -68,7 +70,7 @@ public class GamingNetworkClientToServerWriter extends AbstractWriter implements
if (text.length() > GamingNetwork.MESSAGE_MAX_LENGTH) {
text = text.substring(0, GamingNetwork.MESSAGE_MAX_LENGTH);
}
final byte[] bytes = text.getBytes();
final byte[] bytes = text.getBytes(Charset.forName("utf-8"));
beginMessage(Protocol.CHAT_MESSAGE, 8 + 4 + bytes.length);
this.writeBuffer.putLong(sessionToken);
this.writeBuffer.putInt(bytes.length);

View File

@ -1,6 +1,7 @@
package net.warsmash.uberserver;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import net.warsmash.nio.channels.tcp.TCPClientParser;
@ -48,7 +49,7 @@ public class TCPGamingNetworkServerToClientParser implements TCPClientParser {
else {
reason = null;
}
this.listener.accountCreationFailed(null);
this.listener.accountCreationFailed(reason);
break;
}
case GamingNetworkServerToClientListener.Protocol.LOGIN_OK: {
@ -102,7 +103,7 @@ public class TCPGamingNetworkServerToClientParser implements TCPClientParser {
final int usernameStringLength = Math.min(maxLength, data.getInt());
final byte[] usernameStringBytes = new byte[usernameStringLength];
data.get(usernameStringBytes);
final String username = new String(usernameStringBytes);
final String username = new String(usernameStringBytes, Charset.forName("utf-8"));
return username;
}