-
Notifications
You must be signed in to change notification settings - Fork 89
feat(gui): Distinguish patch players from retail players by a colored name and different status #1404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(gui): Distinguish patch players from retail players by a colored name and different status #1404
Changes from all commits
ad2ed81
06eea3c
9ddafcb
549e098
634eb6b
a059c0b
e1ef9d6
4019d2b
9fb6a01
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -282,6 +282,7 @@ class LANAPI : public LANAPIInterface | |
void handleGameStartTimer( LANMessage *msg, UnsignedInt senderIP ); | ||
void handleGameOptions( LANMessage *msg, UnsignedInt senderIP ); | ||
void handleInActive( LANMessage *msg, UnsignedInt senderIP ); | ||
void handlePatchVersion( LANMessage *msg, UnsignedInt senderIP ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest use terminology "ProductTitle" |
||
|
||
}; | ||
|
||
|
@@ -319,6 +320,7 @@ struct LANMessage | |
MSG_INACTIVE, ///< I've alt-tabbed out. Unaccept me cause I'm a poo-flinging monkey. | ||
|
||
MSG_REQUEST_GAME_INFO, ///< For direct connect, get the game info from a specific IP Address | ||
MSG_PATCH_VERSION, ///< TheSuperHackers patch version | ||
|
||
MSG_MAX | ||
} LANMessageType; | ||
|
@@ -415,6 +417,11 @@ struct LANMessage | |
char options[m_lanMaxOptionsLength+1]; | ||
} GameOptions; | ||
|
||
struct | ||
{ | ||
UnsignedInt patchVersion; | ||
} PatchInfo; | ||
|
||
}; | ||
}; | ||
#pragma pack(pop) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -532,24 +532,28 @@ void PopulateInGameDiplomacyPopup( void ) | |
if (staticTextStatus[rowNum]) | ||
{ | ||
staticTextStatus[rowNum]->winHide(FALSE); | ||
|
||
Color frontColor = 0; | ||
UnicodeString text; | ||
|
||
if (isInGame) | ||
{ | ||
if (isAlive) | ||
{ | ||
staticTextStatus[rowNum]->winSetEnabledTextColors( aliveColor, backColor ); | ||
GadgetStaticTextSetText(staticTextStatus[rowNum], TheGameText->fetch("GUI:PlayerAlive")); | ||
frontColor = aliveColor; | ||
text = TheGameText->fetch("GUI:PlayerAlive"); | ||
} | ||
else | ||
{ | ||
if (isObserver) | ||
{ | ||
staticTextStatus[rowNum]->winSetEnabledTextColors( observerInGameColor, backColor ); | ||
GadgetStaticTextSetText(staticTextStatus[rowNum], TheGameText->fetch("GUI:PlayerObserver")); | ||
frontColor = observerInGameColor; | ||
text = TheGameText->fetch("GUI:PlayerObserver"); | ||
} | ||
else | ||
{ | ||
staticTextStatus[rowNum]->winSetEnabledTextColors( deadColor, backColor ); | ||
GadgetStaticTextSetText(staticTextStatus[rowNum], TheGameText->fetch("GUI:PlayerDead")); | ||
frontColor = deadColor; | ||
text = TheGameText->fetch("GUI:PlayerDead"); | ||
} | ||
} | ||
} | ||
|
@@ -558,15 +562,21 @@ void PopulateInGameDiplomacyPopup( void ) | |
// not in game | ||
if (isObserver) | ||
{ | ||
staticTextStatus[rowNum]->winSetEnabledTextColors( observerGoneColor, backColor ); | ||
GadgetStaticTextSetText(staticTextStatus[rowNum], TheGameText->fetch("GUI:PlayerObserverGone")); | ||
frontColor = observerGoneColor; | ||
text = TheGameText->fetch("GUI:PlayerObserverGone"); | ||
} | ||
else | ||
{ | ||
staticTextStatus[rowNum]->winSetEnabledTextColors( goneColor, backColor ); | ||
GadgetStaticTextSetText(staticTextStatus[rowNum], TheGameText->fetch("GUI:PlayerGone")); | ||
frontColor = goneColor; | ||
text = TheGameText->fetch("GUI:PlayerGone"); | ||
} | ||
} | ||
|
||
if (slot->isHuman() && (TheGameInfo->getLocalSlotNum() == slotNum || slot->getPatchVersion() > 0)) | ||
text.concat(L"[SH]"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This string ideally is build from the product title and not hardcoded like this. |
||
|
||
staticTextStatus[rowNum]->winSetEnabledTextColors(frontColor, backColor); | ||
GadgetStaticTextSetText(staticTextStatus[rowNum], text); | ||
} | ||
|
||
slotNumInRow[rowNum++] = slotNum; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -423,6 +423,12 @@ void UpdateSlotList( GameInfo *myGame, GameWindow *comboPlayer[], | |
} | ||
if(slot->isHuman()) | ||
{ | ||
if (i == myGame->getLocalSlotNum() || myGame->getSlot(i)->getPatchVersion() > 0) | ||
{ | ||
GadgetComboBoxSetEnabledTextColors(comboPlayer[i], 0xFFFFFF00, 0xFF000000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These colours should be put into variables, preferably configurable through INI. |
||
GadgetComboBoxSetDisabledTextColors(comboPlayer[i], 0xFFC0C000, 0xFF000000); | ||
} | ||
|
||
UnicodeString newName = slot->getName(); | ||
UnicodeString oldName = GadgetComboBoxGetText(comboPlayer[i]); | ||
if (comboPlayer[i] && newName.compare(oldName)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,7 @@ | |
#include "Common/crc.h" | ||
#include "Common/GameState.h" | ||
#include "Common/Registry.h" | ||
#include "Common/version.h" | ||
#include "GameNetwork/LANAPI.h" | ||
#include "GameNetwork/networkutil.h" | ||
#include "Common/GlobalData.h" | ||
|
@@ -417,6 +418,9 @@ void LANAPI::update( void ) | |
case LANMessage::MSG_INACTIVE: // someone is telling us that we're inactive. | ||
handleInActive( msg, senderIP ); | ||
break; | ||
case LANMessage::MSG_PATCH_VERSION: // someone is sharing their patch version with us | ||
handlePatchVersion( msg, senderIP ); | ||
break; | ||
|
||
default: | ||
DEBUG_LOG(("Unknown LAN message type %d", msg->LANMessageType)); | ||
|
@@ -461,6 +465,14 @@ void LANAPI::update( void ) | |
} | ||
} | ||
|
||
if (m_inLobby || (m_currentGame && !m_currentGame->isGameInProgress())) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is broadcast every 200 ms to all other clients. It works perfectly, but it's a bit 'spammy'. Should try to find a more elegant solution for this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should only be broadcasted when a new player joins the lobby. It is a fixed value that doesn't change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eliminating the broadcast spam would good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW, the game periodically broadcasts other data that may or may not have changed. This happens with 10 second intervals, which I found to be a bit too slow for this feature.
It's a bit more complicated than that, though. I also need data about the hosts of each game and about other players in the same match. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this needs to be redesigned with new message versions. On RETAIL_COMPATIBLE_NETWORK versions, send the original messages
and on top send new messages, give them a generous offset to avoid colliding with other community products.
Then try to design the packets so that they cover all sorts of use cases we will have. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume I do agree that if we keep There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well ideally we build this feature here without the packet spam every 200 ms. Instead send 2 packets on the announcements, which is better than the spamming. The 2 packets will also only be sent on RETAIL_COMPATIBLE_NETWORK clients, so it is temporary. I did not think this fully through but my instict tells me this is the way to go? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if we understand well enough what our messages will look like after we break retail compatibility, so I propose we delay redesigning them until we have a better idea what that should look like. I think it's possible to avoid spamming There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes you can also send the product version message side by side with other messages. Try to anticipate future requirements for communications so that we do not need to touch it often. |
||
LANMessage msg; | ||
fillInLANMessage(&msg); | ||
msg.LANMessageType = LANMessage::MSG_PATCH_VERSION; | ||
msg.PatchInfo.patchVersion = TheVersion->getVersionNumber(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will only contain major 1 minor 4 for Zero Hour. This means the version will not change between builds. I think this data can be extended with more version information. The least we need is a product name and its version. For reference, see
|
||
sendMessage(&msg); | ||
} | ||
|
||
Bool playerListChanged = false; | ||
Bool gameListChanged = false; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -642,7 +642,8 @@ void LANAPI::OnPlayerList( LANPlayer *playerList ) | |
LANPlayer *player = m_lobbyPlayers; | ||
while (player) | ||
{ | ||
Int addedIndex = GadgetListBoxAddEntryText(listboxPlayers, player->getName(), playerColor, -1, -1); | ||
const Color color = (player->getPatchVersion() > 0 || m_localIP == player->getIP()) ? 0xFFFFFF00 : playerColor; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. magic colour, create INI configurable variable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put it by the others const Color playerColor = GameMakeColor(255,255,255,255); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The current white and grey colors are not configurable either, and I don't see that as an issue.
Will do. |
||
Int addedIndex = GadgetListBoxAddEntryText(listboxPlayers, player->getName(), color, -1, -1); | ||
GadgetListBoxSetItemData(listboxPlayers, (void *)player->getIP(),addedIndex, 0 ); | ||
|
||
if (selectedIP == player->getIP()) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -682,3 +682,58 @@ void LANAPI::handleInActive(LANMessage *msg, UnsignedInt senderIP) { | |
RequestGameOptions(options, FALSE); | ||
lanUpdateSlotList(); | ||
} | ||
|
||
void LANAPI::handlePatchVersion(LANMessage* msg, UnsignedInt senderIP) | ||
{ | ||
if (m_inLobby) | ||
{ | ||
LANPlayer *player = m_lobbyPlayers; | ||
while (player) | ||
{ | ||
if (player->getIP() == senderIP) | ||
{ | ||
if (!player->getPatchVersion() && msg->PatchInfo.patchVersion > 0) | ||
{ | ||
player->setPatchVersion(msg->PatchInfo.patchVersion); | ||
OnPlayerList(m_lobbyPlayers); | ||
} | ||
break; | ||
} | ||
|
||
player = player->getNext(); | ||
} | ||
|
||
LANGameInfo* game = m_games; | ||
while (game) | ||
{ | ||
GameSlot *slot = game->getSlot(0); | ||
if (slot->getIP() == senderIP) | ||
{ | ||
DEBUG_ASSERTCRASH(game->getHostIP() == slot->getIP(), ("First game slot is not used by the host")); | ||
|
||
if (!slot->getPatchVersion() && msg->PatchInfo.patchVersion > 0) | ||
{ | ||
slot->setPatchVersion(msg->PatchInfo.patchVersion); | ||
OnGameList(m_games); | ||
} | ||
break; | ||
} | ||
|
||
game = game->getNext(); | ||
} | ||
} | ||
else if (m_currentGame && !m_currentGame->isGameInProgress()) | ||
{ | ||
for (int player = 0; player < MAX_SLOTS; ++player) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can split this into 2 functions: handlePatchVersionInLobby(LANMessage* msg, UnsignedInt senderIP)
handlePatchVersionInGameRoom(LANMessage* msg, UnsignedInt senderIP) |
||
{ | ||
if (m_currentGame->getIP(player) == senderIP) | ||
{ | ||
if (!m_currentGame->getSlot(player)->getPatchVersion() && msg->PatchInfo.patchVersion > 0) | ||
{ | ||
m_currentGame->getSlot(player)->setPatchVersion(msg->PatchInfo.patchVersion); | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -226,7 +226,10 @@ void LANDisplayGameList( GameWindow *gameListbox, LANGameInfo *gameList ) | |
{ | ||
txtGName.concat(L"]"); | ||
} | ||
Int addedIndex = GadgetListBoxAddEntryText(gameListbox, txtGName, (gameList->isGameInProgress())?gameInProgressColor:gameColor, -1, -1); | ||
const Color color = (gameList->getSlot(0)->getPatchVersion() > 0) | ||
? ((gameList->isGameInProgress()) ? 0xFF808000 : 0xFFFFFF00) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. magic colours |
||
: ((gameList->isGameInProgress()) ? gameInProgressColor : gameColor); | ||
Int addedIndex = GadgetListBoxAddEntryText(gameListbox, txtGName, color, -1, -1); | ||
GadgetListBoxSetItemData(gameListbox, (void *)gameList, addedIndex, 0 ); | ||
|
||
if (selectedPtr == gameList) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can label this as "Community made product version"