Browse Source

Game discovery over ZeroTier

pull/3108/head
Anders Jenbo 4 years ago committed by GitHub
parent
commit
ae90193136
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      Source/DiabloUI/selconn.cpp
  2. 60
      Source/DiabloUI/selgame.cpp
  3. 4
      Source/dvlnet/abstract_net.h
  4. 14
      Source/dvlnet/base_protocol.h
  5. 28
      Source/dvlnet/cdwrap.h
  6. 8
      Source/storm/storm.h
  7. 5
      Source/storm/storm_dvlnet.h
  8. 6
      Source/storm/storm_net.cpp

12
Source/DiabloUI/selconn.cpp

@ -8,6 +8,12 @@
namespace devilution {
int provider;
const char *ConnectionNames[] {
"ZeroTier",
N_("Client-Server (TCP)"),
N_("Loopback"),
};
namespace {
char selconn_MaxPlayers[21];
@ -32,13 +38,13 @@ void SelconnLoad()
#ifndef NONET
#ifndef DISABLE_ZERO_TIER
vecConnItems.push_back(std::make_unique<UiListItem>("Zerotier", SELCONN_ZT));
vecConnItems.push_back(std::make_unique<UiListItem>(ConnectionNames[SELCONN_ZT], SELCONN_ZT));
#endif
#ifndef DISABLE_TCP
vecConnItems.push_back(std::make_unique<UiListItem>(_("Client-Server (TCP)"), SELCONN_TCP));
vecConnItems.push_back(std::make_unique<UiListItem>(_(ConnectionNames[SELCONN_TCP]), SELCONN_TCP));
#endif
#endif
vecConnItems.push_back(std::make_unique<UiListItem>(_("Loopback"), SELCONN_LOOPBACK));
vecConnItems.push_back(std::make_unique<UiListItem>(_(ConnectionNames[SELCONN_LOOPBACK]), SELCONN_LOOPBACK));
UiAddBackground(&vecSelConnDlg);
UiAddLogo(&vecSelConnDlg);

60
Source/DiabloUI/selgame.cpp

@ -38,6 +38,10 @@ const char *title = "";
std::vector<std::unique_ptr<UiListItem>> vecSelGameDlgItems;
std::vector<std::unique_ptr<UiItemBase>> vecSelGameDialog;
std::vector<std::string> Gamelist;
int HighlightedItem;
constexpr const char *DefaultPassword = "asd";
} // namespace
@ -74,7 +78,7 @@ void selgame_GameSelection_Init()
UiAddLogo(&vecSelGameDialog);
SDL_Rect rect1 = { (Sint16)(PANEL_LEFT + 24), (Sint16)(UI_OFFSET_Y + 161), 590, 35 };
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_("Client-Server (TCP)"), rect1, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_(ConnectionNames[provider]), rect1, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
SDL_Rect rect2 = { (Sint16)(PANEL_LEFT + 35), (Sint16)(UI_OFFSET_Y + 211), 205, 192 };
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_("Description:"), rect2, UiFlags::FontSize24 | UiFlags::ColorUiSilver));
@ -88,6 +92,10 @@ void selgame_GameSelection_Init()
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Create Game"), 0));
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Join Game"), 1));
for (unsigned i = 0; i < Gamelist.size(); i++) {
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(Gamelist[i].c_str(), i + 2));
}
vecSelGameDialog.push_back(std::make_unique<UiList>(vecSelGameDlgItems, PANEL_LEFT + 305, (UI_OFFSET_Y + 255), 285, 26, UiFlags::AlignCenter | UiFlags::FontSize24 | UiFlags::ColorUiGold));
SDL_Rect rect5 = { (Sint16)(PANEL_LEFT + 299), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
@ -96,11 +104,12 @@ void selgame_GameSelection_Init()
SDL_Rect rect6 = { (Sint16)(PANEL_LEFT + 449), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("CANCEL"), &UiFocusNavigationEsc, rect6, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
UiInitList(vecSelGameDlgItems.size(), selgame_GameSelection_Focus, selgame_GameSelection_Select, selgame_GameSelection_Esc, vecSelGameDialog, true);
UiInitList(vecSelGameDlgItems.size(), selgame_GameSelection_Focus, selgame_GameSelection_Select, selgame_GameSelection_Esc, vecSelGameDialog, true, nullptr, HighlightedItem);
}
void selgame_GameSelection_Focus(int value)
{
HighlightedItem = value;
switch (vecSelGameDlgItems[value]->m_value) {
case 0:
strncpy(selgame_Description, _("Create a new game with a difficulty setting of your choice."), sizeof(selgame_Description) - 1);
@ -108,6 +117,9 @@ void selgame_GameSelection_Focus(int value)
case 1:
strncpy(selgame_Description, _("Enter an IP or a hostname and join a game already in progress at that address."), sizeof(selgame_Description) - 1);
break;
default:
strncpy(selgame_Description, _("Join the public game already in progress at this address."), sizeof(selgame_Description) - 1);
break;
}
const std::string wrapped = WordWrapString(selgame_Description, DESCRIPTION_WIDTH);
strncpy(selgame_Description, wrapped.data(), sizeof(selgame_Description) - 1);
@ -131,6 +143,13 @@ void selgame_GameSelection_Select(int value)
selgame_enteringGame = true;
selgame_selectedGame = value;
if (value > 1 && selgame_selectedGame != 0) {
strcpy(selgame_Ip, Gamelist[value - 2].c_str());
strcpy(selgame_Password, DefaultPassword);
selgame_Password_Select(value);
return;
}
gfnHeroInfo(UpdateHeroLevel);
selgame_FreeVectors();
@ -184,6 +203,7 @@ void selgame_GameSelection_Select(int value)
SDL_Rect rect7 = { (Sint16)(PANEL_LEFT + 449), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("CANCEL"), &UiFocusNavigationEsc, rect7, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
HighlightedItem = 0;
UiInitList(0, nullptr, selgame_Password_Init, selgame_GameSelection_Init, vecSelGameDialog);
break;
}
@ -281,6 +301,7 @@ void selgame_Diff_Esc()
return;
}
HighlightedItem = 0;
selgame_GameSelection_Init();
}
@ -372,7 +393,7 @@ void selgame_Password_Init(int /*value*/)
UiAddLogo(&vecSelGameDialog);
SDL_Rect rect1 = { (Sint16)(PANEL_LEFT + 24), (Sint16)(UI_OFFSET_Y + 161), 590, 35 };
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_("Client-Server (TCP)"), rect1, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_(ConnectionNames[provider]), rect1, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
SDL_Rect rect2 = { (Sint16)(PANEL_LEFT + 35), (Sint16)(UI_OFFSET_Y + 211), 205, 192 };
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_("Description:"), rect2, UiFlags::FontSize24 | UiFlags::ColorUiSilver));
@ -466,17 +487,50 @@ void selgame_Password_Esc()
selgame_GameSpeedSelection();
}
void RefreshGameList()
{
static uint32_t lastRequest = 0;
static uint32_t lastUpdate = 0;
if (selgame_enteringGame)
return;
uint32_t currentTime = SDL_GetTicks();
if (lastRequest == 0 || currentTime - lastRequest > 30000) {
DvlNet_SendInfoRequest();
lastRequest = currentTime;
lastUpdate = currentTime - 3000; // Give 2 sec for responses, but don't wait 5
}
if (lastUpdate == 0 || currentTime - lastUpdate > 5000) {
std::vector<std::string> gamelist = DvlNet_GetGamelist();
Gamelist.clear();
for (unsigned i = 0; i < gamelist.size(); i++) {
Gamelist.push_back(gamelist[i]);
}
selgame_GameSelection_Init();
lastUpdate = currentTime;
}
}
bool UiSelectGame(GameData *gameData, int *playerId)
{
gdwPlayerId = playerId;
m_game_data = gameData;
LoadBackgroundArt("ui_art\\selgame.pcx");
HighlightedItem = 0;
selgame_GameSelection_Init();
selgame_endMenu = false;
DvlNet_SetPassword(DefaultPassword);
DvlNet_ClearGamelist();
while (!selgame_endMenu) {
UiClearScreen();
UiPollAndRender();
RefreshGameList();
}
selgame_Free();

4
Source/dvlnet/abstract_net.h

@ -48,6 +48,10 @@ public:
{
}
virtual void clear_gamelist()
{
}
virtual std::vector<std::string> get_gamelist()
{
return std::vector<std::string>();

14
Source/dvlnet/base_protocol.h

@ -26,6 +26,7 @@ public:
virtual std::string make_default_gamename();
virtual void send_info_request();
virtual void clear_gamelist();
virtual std::vector<std::string> get_gamelist();
virtual ~base_protocol() = default;
@ -98,9 +99,10 @@ bool base_protocol<P>::wait_firstpeer()
template <class P>
void base_protocol<P>::send_info_request()
{
auto pkt = pktfty->make_packet<PT_INFO_REQUEST>(PLR_BROADCAST,
PLR_MASTER);
proto.send_oob_mc(pkt->Data());
if (wait_network()) {
auto pkt = pktfty->make_packet<PT_INFO_REQUEST>(PLR_BROADCAST, PLR_MASTER);
proto.send_oob_mc(pkt->Data());
}
}
template <class P>
@ -273,6 +275,12 @@ void base_protocol<P>::recv_ingame(packet &pkt, endpoint sender)
RecvLocal(pkt);
}
template <class P>
void base_protocol<P>::clear_gamelist()
{
game_list.clear();
}
template <class P>
std::vector<std::string> base_protocol<P>::get_gamelist()
{

28
Source/dvlnet/cdwrap.h

@ -37,6 +37,10 @@ public:
virtual bool SNetGetTurnsInTransit(uint32_t *turns);
virtual void setup_gameinfo(buffer_t info);
virtual std::string make_default_gamename();
virtual void send_info_request();
virtual void clear_gamelist();
virtual std::vector<std::string> get_gamelist();
virtual void setup_password(std::string pw);
cdwrap();
virtual ~cdwrap() = default;
@ -161,5 +165,29 @@ std::string cdwrap<T>::make_default_gamename()
return dvlnet_wrap->make_default_gamename();
}
template <class T>
void cdwrap<T>::send_info_request()
{
dvlnet_wrap->send_info_request();
}
template <class T>
void cdwrap<T>::clear_gamelist()
{
dvlnet_wrap->clear_gamelist();
}
template <class T>
std::vector<std::string> cdwrap<T>::get_gamelist()
{
return dvlnet_wrap->get_gamelist();
}
template <class T>
void cdwrap<T>::setup_password(std::string pw)
{
return dvlnet_wrap->setup_password(pw);
}
} // namespace net
} // namespace devilution

8
Source/storm/storm.h

@ -8,6 +8,7 @@
#include "appfat.h"
#include "multi.h"
#include "utils/language.h"
#include "utils/stdcompat/string_view.hpp"
namespace devilution {
@ -23,6 +24,8 @@ enum conn_type : uint8_t {
SELCONN_LOOPBACK,
};
extern const char *ConnectionNames[];
struct PCXHeader {
uint8_t Manufacturer;
uint8_t Version;
@ -289,4 +292,9 @@ inline std::uint64_t SFileGetFilePointer(HANDLE hFile)
#endif
void DvlNet_SendInfoRequest();
void DvlNet_ClearGamelist();
std::vector<std::string> DvlNet_GetGamelist();
void DvlNet_SetPassword(std::string pw);
} // namespace devilution

5
Source/storm/storm_dvlnet.h

@ -1,5 +0,0 @@
#pragma once
void DvlNet_SendInfoRequest();
std::vector<std::string> DvlNet_GetGamelist();
void DvlNet_SetPassword(std::string pw);

6
Source/storm/storm_net.cpp

@ -9,7 +9,6 @@
#include "dvlnet/abstract_net.h"
#include "menu.h"
#include "options.h"
#include "storm/storm_dvlnet.h"
#include "utils/stubs.h"
namespace devilution {
@ -219,6 +218,11 @@ void DvlNet_SendInfoRequest()
dvlnet_inst->send_info_request();
}
void DvlNet_ClearGamelist()
{
return dvlnet_inst->clear_gamelist();
}
std::vector<std::string> DvlNet_GetGamelist()
{
return dvlnet_inst->get_gamelist();

Loading…
Cancel
Save