mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2025-12-16 12:08:36 +00:00
Clients can receive chats while in lobby state by having the shell form present a HtMessageBox with the chat and the player is it from. This feature was designed to be used with the moderator whisper command.
389 lines
11 KiB
C++
389 lines
11 KiB
C++
#include "game/lobbyform.h"
|
|
#include "game/createroomform.h"
|
|
#include "game/roomform.h"
|
|
#include "server/room.h"
|
|
|
|
namespace wi {
|
|
|
|
LobbyForm::LobbyForm(LoginHandler& handler, const std::string& server_name) :
|
|
handler_(handler), server_name_(server_name), refresh_(true),
|
|
lurkers_(0), zipdone_(false), selected_main_(false) {
|
|
}
|
|
|
|
LobbyForm::~LobbyForm() {
|
|
}
|
|
|
|
void LobbyForm::ShowJoinMessage(dword result) {
|
|
// Show an appropriate message if it was not a success
|
|
const char *message = NULL;
|
|
switch (result) {
|
|
case knLobbyJoinResultSuccess:
|
|
break;
|
|
case knLobbyJoinResultNotLoggedIn:
|
|
message = "Not logged in";
|
|
break;
|
|
case knLobbyJoinResultFull:
|
|
message = "Lobby is full, try again later.";
|
|
break;
|
|
case knLobbyJoinResultFail:
|
|
default:
|
|
message = "Failure entering lobby";
|
|
break;
|
|
}
|
|
|
|
if (message != NULL) {
|
|
HtMessageBox(kfMbWhiteBorder, "Enter Lobby Problem", message);
|
|
}
|
|
}
|
|
|
|
dword LobbyForm::DoForm(LoginHandler &handler, const std::string& server_name,
|
|
RoomInfo *joininfo) {
|
|
// The user is logged in by the time this gets called.
|
|
LobbyForm *pfrm = (LobbyForm *)gpmfrmm->LoadForm(gpiniForms, kidfLobby,
|
|
new LobbyForm(handler, server_name));
|
|
if (pfrm == NULL) {
|
|
return false;
|
|
}
|
|
int result = 0;
|
|
pfrm->DoModal(&result);
|
|
*joininfo = pfrm->joininfo();
|
|
delete pfrm;
|
|
|
|
if (result == kidcSignOut) {
|
|
return knLobbyResultSignOut;
|
|
}
|
|
if (result == kidcCancel) {
|
|
return knLobbyResultDone;
|
|
}
|
|
if (result == kidcJoinRoom) {
|
|
return knLobbyResultEnterRoom;
|
|
}
|
|
return knLobbyResultDone;
|
|
}
|
|
|
|
bool LobbyForm::DoModal(int *presult, Sfx sfxShow, Sfx sfxHide) {
|
|
char name[kcbPlayerName*2];
|
|
handler_.GetPlayerName(name, sizeof(name));
|
|
LabelControl *plbl = (LabelControl *)GetControlPtr(kidcPlayerName);
|
|
plbl->Show(false);
|
|
plbl = (LabelControl *)GetControlPtr(kidcPlayerNameLabel);
|
|
const char *s = base::Format::ToString("%s / %s", name,
|
|
server_name_.c_str());
|
|
plbl->SetText(s);
|
|
|
|
ListControl *plstc = (ListControl *)GetControlPtr(kidcRoomList);
|
|
Rect rcList;
|
|
plstc->GetRect(&rcList);
|
|
Font *pfnt = plstc->GetFont();
|
|
int cxPrivate = pfnt->GetTextExtent("PRIVATE");
|
|
int cxStart = rcList.Width() / 20; // 10;
|
|
plstc->SetTabStops(0, cxStart, rcList.Width() - cxStart - cxPrivate);
|
|
plstc->SetTabFlags(0, kfLstTabEllipsis, 0);
|
|
GetControlPtr(kidcJoinRoom)->Show(false);
|
|
|
|
Show(true);
|
|
gptra->SetCallback(this);
|
|
dword result = gptra->JoinLobby(this);
|
|
if (result != knLobbyJoinResultSuccess) {
|
|
gptra->SetCallback(NULL);
|
|
ShowJoinMessage(result);
|
|
*presult = 0;
|
|
return false;
|
|
}
|
|
bool success = ShellForm::DoModal(presult, sfxShow, sfxHide);
|
|
gptra->LeaveLobby();
|
|
gptra->SetCallback(NULL);
|
|
|
|
return success;
|
|
}
|
|
|
|
void LobbyForm::OnControlSelected(word idc) {
|
|
switch (idc) {
|
|
case kidcNewRoom:
|
|
OnCreateRoom();
|
|
break;
|
|
|
|
case kidcJoinRoom:
|
|
OnJoinRoom();
|
|
break;
|
|
|
|
case kidcCancel:
|
|
case kidcSignOut:
|
|
EndForm(idc);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void LobbyForm::OnControlNotify(word idc, int nNotify) {
|
|
if (idc == kidcRoomList && nNotify == knNotifySelectionChange) {
|
|
Refresh(0);
|
|
}
|
|
Form::OnControlNotify(idc, nNotify);
|
|
}
|
|
|
|
void LobbyForm::OnJoinRoom() {
|
|
ListControl *plstc = (ListControl *)GetControlPtr(kidcRoomList);
|
|
dword roomid = (dword)(pword)plstc->GetSelectedItemData();
|
|
RoomMap::iterator it = map_.find(roomid);
|
|
if (it == map_.end()) {
|
|
return;
|
|
}
|
|
if (it->second.priv) {
|
|
HostInitiateAsk("Enter Password:", kcbPassword - 1,
|
|
it->second.password.c_str(), knKeyboardAskDefault,
|
|
true);
|
|
return;
|
|
}
|
|
InitiateJoinRoom(it->second);
|
|
}
|
|
|
|
void LobbyForm::OnCreateRoom() {
|
|
char roomname[kcbRoomname];
|
|
char password[kcbPassword];
|
|
if (!CreateRoomForm::DoForm(roomname, sizeof(roomname), password,
|
|
sizeof(password))) {
|
|
return;
|
|
}
|
|
|
|
if (gptra == NULL) {
|
|
return;
|
|
}
|
|
|
|
dword roomid;
|
|
dword result = gptra->CreateRoom(roomname, password, &roomid);
|
|
switch (result) {
|
|
case knLobbyCreateRoomResultSuccess:
|
|
{
|
|
// Update the list and select the created room, in case
|
|
// the join fails.
|
|
Refresh(-1);
|
|
ListControl *plstc = (ListControl *)GetControlPtr(kidcRoomList);
|
|
refresh_ = false;
|
|
plstc->Select(FindIndex(roomid), true, true);
|
|
refresh_ = true;
|
|
|
|
// OnAddRoom has been called already. Shove the password
|
|
// into the info and join the room.
|
|
RoomMap::iterator it = map_.find(roomid);
|
|
if (it != map_.end()) {
|
|
it->second.password = password;
|
|
InitiateJoinRoom(it->second);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case knLobbyCreateRoomResultFail:
|
|
HtMessageBox(kfMbWhiteBorder, "Create Room",
|
|
"Error creating this room.");
|
|
break;
|
|
|
|
case knLobbyCreateRoomResultFull:
|
|
HtMessageBox(kfMbWhiteBorder, "Create Room", "Too many rooms. Join an existing room");
|
|
break;
|
|
|
|
case knLobbyCreateRoomResultExists:
|
|
HtMessageBox(kfMbWhiteBorder, "Create Room",
|
|
"A room with this name already exists.");
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
int LobbyForm::FindIndex(dword roomid) {
|
|
int index = 0;
|
|
RoomMap::iterator it = map_.begin();
|
|
for (; it != map_.end(); it++) {
|
|
if (it->first == roomid) {
|
|
return index;
|
|
}
|
|
index++;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void LobbyForm::InitiateJoinRoom(const RoomInfo& info) {
|
|
if (gptra == NULL) {
|
|
return;
|
|
}
|
|
|
|
// Before joining, check to see if this room is joinable.
|
|
// Actually joining also checks, but this is a way to provide the user
|
|
// with feedback before exiting this form (actual joining happens
|
|
// in RoomForm).
|
|
dword result = gptra->CanJoinRoom(info.roomid, info.password.c_str());
|
|
RoomForm::ShowJoinMessage(result);
|
|
switch (result) {
|
|
case knRoomJoinResultWrongPassword:
|
|
OnJoinRoom();
|
|
break;
|
|
|
|
case knRoomJoinResultSuccess:
|
|
joininfo_ = info;
|
|
EndForm(kidcJoinRoom);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void LobbyForm::Refresh(int ct) {
|
|
if (!refresh_) {
|
|
return;
|
|
}
|
|
if (ct == -1) {
|
|
timer_.Stop();
|
|
OnTimeout(0);
|
|
return;
|
|
}
|
|
if (ct == 0) {
|
|
timer_.Stop();
|
|
}
|
|
if (timer_.IsStarted()) {
|
|
return;
|
|
}
|
|
timer_.Start(this, ct * 10);
|
|
}
|
|
|
|
void LobbyForm::OnTimeout(int id) {
|
|
refresh_ = false;
|
|
ListControl *plstc = (ListControl *)GetControlPtr(kidcRoomList);
|
|
dword roomid = (dword)(pword)plstc->GetSelectedItemData();
|
|
if (!selected_main_) {
|
|
roomid = kroomidMain;
|
|
}
|
|
plstc->Clear();
|
|
RoomMap::iterator it = map_.begin();
|
|
for (; it != map_.end(); it++) {
|
|
RoomInfo& info = it->second;
|
|
const char *s;
|
|
if (info.priv) {
|
|
s = base::Format::ToString("\t%s (%d %s, %d %s)\tPRIVATE",
|
|
info.name.c_str(), info.cPlayers,
|
|
info.cPlayers == 1 ? "player" : "players",
|
|
info.cGames,
|
|
info.cGames == 1 ? "game" : "games");
|
|
} else {
|
|
s = base::Format::ToString("\t%s (%d %s, %d %s)",
|
|
info.name.c_str(), info.cPlayers,
|
|
info.cPlayers == 1 ? "player" : "players",
|
|
info.cGames,
|
|
info.cGames == 1 ? "game" : "games");
|
|
}
|
|
plstc->Add(s, (void *)(pword)info.roomid);
|
|
}
|
|
int selected = FindIndex(roomid);
|
|
if (selected < 0 && map_.size() != 0) {
|
|
plstc->Select(0, true, true);
|
|
} else {
|
|
plstc->Select(selected, true);
|
|
selected_main_ = true;
|
|
}
|
|
Control *pctl = GetControlPtr(kidcJoinRoom);
|
|
refresh_ = true;
|
|
pctl->Show(plstc->GetSelectedItemIndex() >= 0);
|
|
}
|
|
|
|
void LobbyForm::OnLurkerCount(dword count) {
|
|
lurkers_ = count;
|
|
if (zipdone_) {
|
|
LabelControl *plbl = (LabelControl *)GetControlPtr(kidcLurkerCount);
|
|
plbl->SetText(base::Format::ToString("Lurkers: %d", count));
|
|
}
|
|
}
|
|
|
|
void LobbyForm::OnZipDone() {
|
|
zipdone_ = true;
|
|
OnLurkerCount(lurkers_);
|
|
}
|
|
|
|
void LobbyForm::OnAddRoom(const char *name, dword roomid, bool priv,
|
|
dword cPlayers, dword cGames) {
|
|
RoomInfo info;
|
|
info.name = name;
|
|
info.roomid = roomid;
|
|
info.priv = priv;
|
|
info.cPlayers = cPlayers;
|
|
info.cGames = cGames;
|
|
map_.insert(RoomMap::value_type(roomid, info));
|
|
Refresh();
|
|
}
|
|
|
|
void LobbyForm::OnRemoveRoom(dword roomid) {
|
|
RoomMap::iterator it = map_.find(roomid);
|
|
if (it == map_.end()) {
|
|
LOG() << "Couldn't find room!";
|
|
return;
|
|
}
|
|
map_.erase(it);
|
|
Refresh();
|
|
}
|
|
|
|
void LobbyForm::OnUpdateRoom(dword roomid, dword cPlayers, dword cGames) {
|
|
RoomMap::iterator it = map_.find(roomid);
|
|
if (it == map_.end()) {
|
|
LOG() << "Couldn't find room!";
|
|
return;
|
|
}
|
|
it->second.cPlayers = cPlayers;
|
|
it->second.cGames = cGames;
|
|
Refresh();
|
|
}
|
|
|
|
void LobbyForm::OnStatusUpdate(char *pszStatus) {
|
|
}
|
|
|
|
void LobbyForm::OnConnectionClose() {
|
|
Event evt;
|
|
memset(&evt, 0, sizeof(evt));
|
|
evt.idf = m_idf;
|
|
evt.eType = connectionCloseEvent;
|
|
gevm.PostEvent(&evt);
|
|
}
|
|
|
|
void LobbyForm::OnShowMessage(const char *message) {
|
|
message_ = message;
|
|
Event evt;
|
|
memset(&evt, 0, sizeof(evt));
|
|
evt.idf = m_idf;
|
|
evt.eType = showMessageEvent;
|
|
gevm.PostEvent(&evt);
|
|
}
|
|
|
|
bool LobbyForm::OnFilterEvent(Event *pevt) {
|
|
if (pevt->eType == askStringEvent) {
|
|
if (gptra == NULL) {
|
|
return true;
|
|
}
|
|
|
|
char s[512];
|
|
HostGetAskString(s, sizeof(s));
|
|
|
|
ListControl *plstc = (ListControl *)GetControlPtr(kidcRoomList);
|
|
dword roomid = (dword)(pword)plstc->GetSelectedItemData();
|
|
RoomMap::iterator it = map_.find(roomid);
|
|
if (it != map_.end()) {
|
|
it->second.password = s;
|
|
InitiateJoinRoom(it->second);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (pevt->eType == connectionCloseEvent) {
|
|
HtMessageBox(kfMbWhiteBorder, "Comm Problem", "The server has closed your connection.");
|
|
EndForm(kidcCancel);
|
|
return true;
|
|
}
|
|
|
|
if (pevt->eType == showMessageEvent) {
|
|
HtMessageBox(kfMbWhiteBorder, "Server Message", message_.c_str());
|
|
message_ = "";
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void LobbyForm::OnReceiveChat(const char *player, const char *chat) {
|
|
const char *s = base::Format::ToString("%s: %s", player, chat);
|
|
HtMessageBox(kfMbWhiteBorder | kfMbKeepTimersEnabled, player, s);
|
|
}
|
|
|
|
} // namespace wi
|