1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-08 22:26:51 +02:00

Added support for configuring which language channels are visible to

player in lobby
This commit is contained in:
Ivan Savenko
2025-01-26 11:22:11 +00:00
parent 64bb3099f6
commit 9d7c4a60e0
32 changed files with 541 additions and 49 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

View File

@@ -199,6 +199,7 @@
"vcmi.lobby.preview.error.invite" : "You were not invited to this room.",
"vcmi.lobby.preview.error.mods" : "You are using different set of mods.",
"vcmi.lobby.preview.error.version" : "You are using different version of VCMI.",
"vcmi.lobby.channel.add" : "Add Channel",
"vcmi.lobby.room.new" : "New Game",
"vcmi.lobby.room.load" : "Load Game",
"vcmi.lobby.room.type" : "Room Type",

View File

@@ -199,6 +199,7 @@
"vcmi.lobby.preview.error.invite" : "Ви не були запрошені до цієї кімнати.",
"vcmi.lobby.preview.error.mods" : "Ви використовуєте інший набір модифікацій.",
"vcmi.lobby.preview.error.version" : "Ви використовуєте іншу версію VCMI.",
"vcmi.lobby.channel.add" : "Додати канал чату",
"vcmi.lobby.room.new" : "Нова гра",
"vcmi.lobby.room.load" : "Завантажити гру",
"vcmi.lobby.room.type" : "Тип кімнати",

View File

@@ -109,6 +109,7 @@ set(vcmiclientcommon_SRCS
renderSDL/ScreenHandler.cpp
renderSDL/SDL_Extensions.cpp
globalLobby/GlobalLobbyAddChannelWindow.cpp
globalLobby/GlobalLobbyClient.cpp
globalLobby/GlobalLobbyInviteWindow.cpp
globalLobby/GlobalLobbyLoginWindow.cpp
@@ -322,6 +323,7 @@ set(vcmiclientcommon_HEADERS
globalLobby/GlobalLobbyClient.h
globalLobby/GlobalLobbyDefines.h
globalLobby/GlobalLobbyAddChannelWindow.h
globalLobby/GlobalLobbyInviteWindow.h
globalLobby/GlobalLobbyLoginWindow.h
globalLobby/GlobalLobbyRoomWindow.h

View File

@@ -0,0 +1,86 @@
/*
* GlobalLobbyAddChannelWindow.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "GlobalLobbyAddChannelWindow.h"
#include "GlobalLobbyClient.h"
#include "../CServerHandler.h"
#include "../gui/CGuiHandler.h"
#include "../gui/Shortcut.h"
#include "../gui/WindowHandler.h"
#include "../widgets/Buttons.h"
#include "../widgets/GraphicalPrimitiveCanvas.h"
#include "../widgets/Images.h"
#include "../widgets/ObjectLists.h"
#include "../widgets/TextControls.h"
#include "../../lib/texts/MetaString.h"
#include "../../lib/texts/Languages.h"
GlobalLobbyAddChannelWindowCard::GlobalLobbyAddChannelWindowCard(const std::string & languageID)
: languageID(languageID)
{
pos.w = 200;
pos.h = 40;
addUsedEvents(LCLICK);
OBJECT_CONSTRUCTION;
const auto & language = Languages::getLanguageOptions(languageID);
backgroundOverlay = std::make_shared<TransparentFilledRectangle>(Rect(0, 0, pos.w, pos.h), ColorRGBA(0, 0, 0, 128), ColorRGBA(64, 64, 64, 64), 1);
labelNameNative = std::make_shared<CLabel>(5, 10, FONT_SMALL, ETextAlignment::CENTERLEFT, Colors::WHITE, language.nameNative);
if (language.nameNative != language.nameEnglish)
labelNameTranslated = std::make_shared<CLabel>(5, 30, FONT_SMALL, ETextAlignment::CENTERLEFT, Colors::WHITE, language.nameEnglish);
}
void GlobalLobbyAddChannelWindowCard::clickPressed(const Point & cursorPosition)
{
CSH->getGlobalLobby().addChannel(languageID);
GH.windows().popWindows(1);
}
GlobalLobbyAddChannelWindow::GlobalLobbyAddChannelWindow()
: CWindowObject(BORDERED)
{
OBJECT_CONSTRUCTION;
pos.w = 236;
pos.h = 420;
filledBackground = std::make_shared<FilledTexturePlayerColored>(Rect(0, 0, pos.w, pos.h));
filledBackground->setPlayerColor(PlayerColor(1));
labelTitle = std::make_shared<CLabel>(
pos.w / 2, 20, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, MetaString::createFromTextID("vcmi.lobby.channel.add").toString()
);
const auto & allLanguages = Languages::getLanguageList();
std::vector<std::string> newLanguages;
for (const auto & language : allLanguages)
if (!vstd::contains(CSH->getGlobalLobby().getActiveChannels(), language.identifier))
newLanguages.push_back(language.identifier);
const auto & createChannelCardCallback = [newLanguages](size_t index) -> std::shared_ptr<CIntObject>
{
if(index < newLanguages.size())
return std::make_shared<GlobalLobbyAddChannelWindowCard>(newLanguages[index]);
return std::make_shared<CIntObject>();
};
listBackground = std::make_shared<TransparentFilledRectangle>(Rect(8, 48, 220, 324), ColorRGBA(0, 0, 0, 64), ColorRGBA(64, 80, 128, 255), 1);
languageList = std::make_shared<CListBox>(createChannelCardCallback, Point(10, 50), Point(0, 40), 8, newLanguages.size(), 0, 1 | 4, Rect(200, 0, 320, 320));
languageList->setRedrawParent(true);
buttonClose = std::make_shared<CButton>(Point(86, 384), AnimationPath::builtin("MuBcanc"), CButton::tooltip(), [this]() { close(); }, EShortcut::GLOBAL_RETURN );
center();
}

View File

@@ -0,0 +1,46 @@
/*
* GlobalLobbyInviteWindow.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "GlobalLobbyObserver.h"
#include "../windows/CWindowObject.h"
class CLabel;
class FilledTexturePlayerColored;
class TransparentFilledRectangle;
class CListBox;
class CButton;
struct GlobalLobbyAccount;
class GlobalLobbyAddChannelWindow final : public CWindowObject
{
std::shared_ptr<FilledTexturePlayerColored> filledBackground;
std::shared_ptr<CLabel> labelTitle;
std::shared_ptr<CListBox> languageList;
std::shared_ptr<TransparentFilledRectangle> listBackground;
std::shared_ptr<CButton> buttonClose;
public:
GlobalLobbyAddChannelWindow();
};
class GlobalLobbyAddChannelWindowCard : public CIntObject
{
std::string languageID;
std::shared_ptr<TransparentFilledRectangle> backgroundOverlay;
std::shared_ptr<CLabel> labelNameNative;
std::shared_ptr<CLabel> labelNameTranslated;
void clickPressed(const Point & cursorPosition) override;
public:
GlobalLobbyAddChannelWindowCard(const std::string & languageID);
};

View File

@@ -32,9 +32,54 @@
GlobalLobbyClient::GlobalLobbyClient()
{
activeChannels.emplace_back("english");
if (CGI->generaltexth->getPreferredLanguage() != "english")
activeChannels.emplace_back(CGI->generaltexth->getPreferredLanguage());
auto customChannels = settings["lobby"]["languageRooms"].convertTo<std::vector<std::string>>();
if (customChannels.empty())
{
activeChannels.emplace_back("english");
if (CGI->generaltexth->getPreferredLanguage() != "english")
activeChannels.emplace_back(CGI->generaltexth->getPreferredLanguage());
}
else
{
activeChannels = customChannels;
}
}
void GlobalLobbyClient::addChannel(const std::string & channel)
{
activeChannels.emplace_back(channel);
auto lobbyWindowPtr = lobbyWindow.lock();
if(lobbyWindowPtr)
lobbyWindowPtr->refreshActiveChannels();
JsonNode toSend;
toSend["type"].String() = "requestChatHistory";
toSend["channelType"].String() = "global";
toSend["channelName"].String() = channel;
CSH->getGlobalLobby().sendMessage(toSend);
Settings languageRooms = settings.write["lobby"]["languageRooms"];
languageRooms->Vector().clear();
for (const auto & lang : activeChannels)
languageRooms->Vector().push_back(JsonNode(lang));
}
void GlobalLobbyClient::closeChannel(const std::string & channel)
{
vstd::erase(activeChannels, channel);
auto lobbyWindowPtr = lobbyWindow.lock();
if(lobbyWindowPtr)
lobbyWindowPtr->refreshActiveChannels();
Settings languageRooms = settings.write["lobby"]["languageRooms"];
languageRooms->Vector().clear();
for (const auto & lang : activeChannels)
languageRooms->Vector().push_back(JsonNode(lang));
}
GlobalLobbyClient::~GlobalLobbyClient() = default;
@@ -347,6 +392,10 @@ void GlobalLobbyClient::sendClientLogin()
toSend["accountCookie"].String() = getAccountCookie();
toSend["language"].String() = CGI->generaltexth->getPreferredLanguage();
toSend["version"].String() = VCMI_VERSION_STRING;
for (const auto & language : activeChannels)
toSend["languageRooms"].Vector().push_back(JsonNode(language));
sendMessage(toSend);
}

View File

@@ -92,6 +92,8 @@ public:
void sendClientRegister(const std::string & accountName);
void sendClientLogin();
void sendOpenRoom(const std::string & mode, int playerLimit);
void addChannel(const std::string & channel);
void closeChannel(const std::string & channel);
void sendProxyConnectionLogin(const NetworkConnectionPtr & netConnection);
void resetMatchState();

View File

@@ -11,9 +11,10 @@
#include "StdInc.h"
#include "GlobalLobbyWidget.h"
#include "GlobalLobbyAddChannelWindow.h"
#include "GlobalLobbyClient.h"
#include "GlobalLobbyWindow.h"
#include "GlobalLobbyRoomWindow.h"
#include "GlobalLobbyWindow.h"
#include "../CGameInfo.h"
#include "../CServerHandler.h"
@@ -72,6 +73,18 @@ GlobalLobbyWidget::CreateFunc GlobalLobbyWidget::getItemListConstructorFunc(cons
if(index < channels.size())
return std::make_shared<GlobalLobbyChannelCard>(this->window, channels[index]);
if(index == channels.size())
{
const auto buttonCallback = [](){
GH.windows().createAndPushWindow<GlobalLobbyAddChannelWindow>();
};
auto result = std::make_shared<CButton>(Point(0,0), AnimationPath::builtin("lobbyAddChannel"), CButton::tooltip(), buttonCallback);
result->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("lobby/addChannel")));
return result;
}
return std::make_shared<CIntObject>();
};
@@ -255,6 +268,13 @@ GlobalLobbyChannelCard::GlobalLobbyChannelCard(GlobalLobbyWindow * window, const
{
OBJECT_CONSTRUCTION;
labelName = std::make_shared<CLabel>(5, 20, FONT_SMALL, ETextAlignment::CENTERLEFT, Colors::WHITE, Languages::getLanguageOptions(channelName).nameNative);
if (CSH->getGlobalLobby().getActiveChannels().size() > 1)
{
pos.w = 110;
buttonClose = std::make_shared<CButton>(Point(113, 7), AnimationPath::builtin("lobbyCloseChannel"), CButton::tooltip(), [channelName](){CSH->getGlobalLobby().closeChannel(channelName);});
buttonClose->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("lobby/closeChannel")));
}
}
GlobalLobbyMatchCard::GlobalLobbyMatchCard(GlobalLobbyWindow * window, const GlobalLobbyRoom & matchDescription)

View File

@@ -77,7 +77,6 @@ class GlobalLobbyRoomCard : public CIntObject
std::shared_ptr<CLabel> labelRoomSize;
std::shared_ptr<CLabel> labelRoomStatus;
std::shared_ptr<CLabel> labelDescription;
std::shared_ptr<CButton> buttonJoin;
std::shared_ptr<CPicture> iconRoomSize;
void clickPressed(const Point & cursorPosition) override;
@@ -88,6 +87,7 @@ public:
class GlobalLobbyChannelCard : public GlobalLobbyChannelCardBase
{
std::shared_ptr<CLabel> labelName;
std::shared_ptr<CButton> buttonClose;
public:
GlobalLobbyChannelCard(GlobalLobbyWindow * window, const std::string & channelName);

View File

@@ -39,6 +39,7 @@ GlobalLobbyWindow::GlobalLobbyWindow()
doOpenChannel("global", "english", Languages::getLanguageOptions("english").nameNative);
widget->getChannelListHeader()->setText(MetaString::createFromTextID("vcmi.lobby.header.channels").toString());
widget->getChannelList()->resize(CSH->getGlobalLobby().getActiveChannels().size()+1);
}
bool GlobalLobbyWindow::isChannelOpen(const std::string & testChannelType, const std::string & testChannelName) const
@@ -182,6 +183,21 @@ void GlobalLobbyWindow::onMatchesHistory(const std::vector<GlobalLobbyRoom> & hi
widget->getMatchListHeader()->setText(text.toString());
}
void GlobalLobbyWindow::refreshActiveChannels()
{
const auto & activeChannels = CSH->getGlobalLobby().getActiveChannels();
if (activeChannels.size()+1 == widget->getChannelList()->size())
widget->getChannelList()->reset();
else
widget->getChannelList()->resize(activeChannels.size()+1);
if (currentChannelType == "global" && !vstd::contains(activeChannels, currentChannelName) && !activeChannels.empty())
{
doOpenChannel("global", activeChannels.front(), Languages::getLanguageOptions(activeChannels.front()).nameNative);
}
}
void GlobalLobbyWindow::onInviteReceived(const std::string & invitedRoomID)
{
widget->getRoomList()->reset();

View File

@@ -45,6 +45,7 @@ public:
void onGameChatMessage(const std::string & sender, const std::string & message, const std::string & when, const std::string & channelType, const std::string & channelName);
void refreshChatText();
void refreshActiveChannels();
void onActiveAccounts(const std::vector<GlobalLobbyAccount> & accounts) override;
void onActiveGameRooms(const std::vector<GlobalLobbyRoom> & rooms) override;
void onMatchesHistory(const std::vector<GlobalLobbyRoom> & history);

View File

@@ -127,27 +127,29 @@ size_t CTrueTypeFont::getStringWidthScaled(const std::string & text) const
void CTrueTypeFont::renderText(SDL_Surface * surface, const std::string & data, const ColorRGBA & color, const Point & pos) const
{
if (color.r != 0 && color.g != 0 && color.b != 0) // not black - add shadow
{
if (outline)
renderText(surface, data, Colors::BLACK, pos - Point(1,1) * getScalingFactor());
if (data.empty())
return;
if (dropShadow || outline)
renderText(surface, data, Colors::BLACK, pos + Point(1,1) * getScalingFactor());
}
if (outline)
renderTextImpl(surface, data, Colors::BLACK, pos - Point(1,1) * getScalingFactor());
if (!data.empty())
{
SDL_Surface * rendered;
if (blended)
rendered = TTF_RenderUTF8_Blended(font.get(), data.c_str(), CSDL_Ext::toSDL(color));
else
rendered = TTF_RenderUTF8_Solid(font.get(), data.c_str(), CSDL_Ext::toSDL(color));
if (dropShadow || outline)
renderTextImpl(surface, data, Colors::BLACK, pos + Point(1,1) * getScalingFactor());
assert(rendered);
CSDL_Ext::blitSurface(rendered, surface, pos);
SDL_FreeSurface(rendered);
}
renderTextImpl(surface, data, color, pos);
}
void CTrueTypeFont::renderTextImpl(SDL_Surface * surface, const std::string & data, const ColorRGBA & color, const Point & pos) const
{
SDL_Surface * rendered;
if (blended)
rendered = TTF_RenderUTF8_Blended(font.get(), data.c_str(), CSDL_Ext::toSDL(color));
else
rendered = TTF_RenderUTF8_Solid(font.get(), data.c_str(), CSDL_Ext::toSDL(color));
assert(rendered);
CSDL_Ext::blitSurface(rendered, surface, pos);
SDL_FreeSurface(rendered);
}

View File

@@ -34,6 +34,7 @@ class CTrueTypeFont final : public IFont
int getFontStyle(const JsonNode & config) const;
void renderText(SDL_Surface * surface, const std::string & data, const ColorRGBA & color, const Point & pos) const override;
void renderTextImpl(SDL_Surface * surface, const std::string & data, const ColorRGBA & color, const Point & pos) const;
size_t getFontAscentScaled() const override;
public:
CTrueTypeFont(const JsonNode & fontConfig);

View File

@@ -113,24 +113,32 @@ size_t FontChain::getGlyphWidthScaled(const char * data) const
std::vector<FontChain::TextChunk> FontChain::splitTextToChunks(const std::string & data) const
{
// U+FFFD - replacement character (question mark in rhombus)
static const std::string replacementCharacter = u8"";
std::vector<TextChunk> chunks;
const auto & selectFont = [this](const char * characterPtr) -> const IFont *
{
for(const auto & font : chain)
if (font->canRepresentCharacter(characterPtr))
return font.get();
return nullptr;
};
for (size_t i = 0; i < data.size(); i += TextOperations::getUnicodeCharacterSize(data[i]))
{
const IFont * currentFont = nullptr;
for(const auto & font : chain)
std::string symbol = data.substr(i, TextOperations::getUnicodeCharacterSize(data[i]));
const IFont * currentFont = selectFont(symbol.data());
if (currentFont == nullptr)
{
if (font->canRepresentCharacter(data.data() + i))
{
currentFont = font.get();
break;
}
symbol = replacementCharacter;
currentFont = selectFont(symbol.data());
}
if (currentFont == nullptr)
continue; // not representable
std::string symbol = data.substr(i, TextOperations::getUnicodeCharacterSize(data[i]));
continue; // Still nothing - neither desired character nor fallback can be rendered
if (chunks.empty() || chunks.back().font != currentFont)
chunks.push_back({currentFont, symbol});

View File

@@ -32,6 +32,12 @@
{
"type" : "string",
"description" : "Version of client, e.g. 1.5.0"
},
"languageRooms" :
{
"type" : "array",
"items" : { "type" : "string" },
"description" : "(since 1.6.4) List of language rooms for which player wants to receive chat history"
}
}
}

View File

@@ -673,7 +673,7 @@
"type" : "object",
"additionalProperties" : false,
"default" : {},
"required" : [ "mapPreview", "hostname", "port", "roomPlayerLimit", "roomType", "roomMode" ],
"required" : [ "mapPreview", "hostname", "port", "roomPlayerLimit", "roomType", "roomMode", "languageRooms" ],
"properties" : {
"mapPreview" : {
"type" : "boolean",
@@ -698,6 +698,10 @@
"roomMode" : {
"type" : "number",
"default" : 0
},
"languageRooms" : {
"type" : "array",
"default" : []
}
}
},

View File

@@ -0,0 +1,118 @@
{
"normal" : {
"width": 146,
"height": 40,
"items" : [
{
"type": "texture",
"image": "DiBoxBck",
"color" : "blue",
"rect": {"x": 0, "y": 0, "w": 146, "h": 40}
},
{
"type": "graphicalPrimitive",
"rect": {"x": 0, "y": 0, "w": 146, "h": 40},
"primitives" : [
{ "type" : "filledBox", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : -3, "y" : -3}, "color" : [ 0, 0, 0, 128 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : 0, "y" : -1}, "color" : [ 255, 255, 255, 64 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : -1, "y" : 0}, "color" : [ 255, 255, 255, 128 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : 1, "y" : -2}, "color" : [ 255, 255, 255, 80 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : -2, "y" : 1}, "color" : [ 255, 255, 255, 160 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : -2}, "b" : { "x" : -2, "y" : -2}, "color" : [ 0, 0, 0, 192 ] },
{ "type" : "line", "a" : { "x" : -2, "y" : 1}, "b" : { "x" : -2, "y" : -2}, "color" : [ 0, 0, 0, 192 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : -1}, "b" : { "x" : -1, "y" : -1}, "color" : [ 0, 0, 0, 255 ] },
{ "type" : "line", "a" : { "x" : -1, "y" : 0}, "b" : { "x" : -1, "y" : -1}, "color" : [ 0, 0, 0, 255 ] },
]
}
]
},
"pressed" : {
"width": 146,
"height": 40,
"items" : [
{
"type": "texture",
"image": "DiBoxBck",
"color" : "blue",
"rect": {"x": 1, "y": 1, "w": 145, "h": 39}
},
{
"type": "graphicalPrimitive",
"rect": {"x": 0, "y": 0, "w": 146, "h": 40},
"primitives" : [
{ "type" : "filledBox", "a" : { "x" : 3, "y" : 3}, "b" : { "x" : -3, "y" : -3}, "color" : [ 0, 0, 0, 160 ] },
{ "type" : "rectangle", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : -1, "y" : -1}, "color" : [ 0, 0, 0, 255 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : 1, "y" : -2}, "color" : [ 255, 255, 255, 48 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : -2, "y" : 1}, "color" : [ 255, 255, 255, 96 ] },
{ "type" : "line", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : 2, "y" : -3}, "color" : [ 255, 255, 255, 64 ] },
{ "type" : "line", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : -3, "y" : 2}, "color" : [ 255, 255, 255, 128 ] },
]
}
]
},
"blocked" : {
"width": 146,
"height": 40,
"items" : [
{
"type": "texture",
"image": "DiBoxBck",
"color" : "blue",
"rect": {"x": 0, "y": 0, "w": 146, "h": 40}
},
{
"type": "graphicalPrimitive",
"rect": {"x": 0, "y": 0, "w": 146, "h": 40},
"primitives" : [
{ "type" : "filledBox", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : -3, "y" : -3}, "color" : [ 0, 0, 0, 128 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : 0, "y" : -1}, "color" : [ 255, 255, 255, 64 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : -1, "y" : 0}, "color" : [ 255, 255, 255, 128 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : 1, "y" : -2}, "color" : [ 255, 255, 255, 80 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : -2, "y" : 1}, "color" : [ 255, 255, 255, 160 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : -2}, "b" : { "x" : -2, "y" : -2}, "color" : [ 0, 0, 0, 192 ] },
{ "type" : "line", "a" : { "x" : -2, "y" : 1}, "b" : { "x" : -2, "y" : -2}, "color" : [ 0, 0, 0, 192 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : -1}, "b" : { "x" : -1, "y" : -1}, "color" : [ 0, 0, 0, 255 ] },
{ "type" : "line", "a" : { "x" : -1, "y" : 0}, "b" : { "x" : -1, "y" : -1}, "color" : [ 0, 0, 0, 255 ] },
]
}
]
},
"highlighted" : {
"width": 146,
"height": 40,
"items" : [
{
"type": "texture",
"image": "DiBoxBck",
"color" : "blue",
"rect": {"x": 0, "y": 0, "w": 146, "h": 40}
},
{
"type": "graphicalPrimitive",
"rect": {"x": 0, "y": 0, "w": 146, "h": 40},
"primitives" : [
{ "type" : "filledBox", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : -3, "y" : -3}, "color" : [ 0, 0, 0, 128 ] },
{ "type" : "rectangle", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : -3, "y" : -3}, "color" : [ 255, 255, 255, 255 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : -2}, "b" : { "x" : -2, "y" : -2}, "color" : [ 255, 255, 255, 255 ] },
{ "type" : "line", "a" : { "x" : -2, "y" : 1}, "b" : { "x" : -2, "y" : -2}, "color" : [ 255, 255, 255, 255 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : 1, "y" : -2}, "color" : [ 255, 255, 255, 160 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : -2, "y" : 1}, "color" : [ 255, 255, 255, 160 ] },
]
}
]
},
}

View File

@@ -0,0 +1,118 @@
{
"normal" : {
"width": 25,
"height": 25,
"items" : [
{
"type": "texture",
"image": "DiBoxBck",
"color" : "blue",
"rect": {"x": 0, "y": 0, "w": 25, "h": 25}
},
{
"type": "graphicalPrimitive",
"rect": {"x": 0, "y": 0, "w": 25, "h": 25},
"primitives" : [
{ "type" : "filledBox", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : -3, "y" : -3}, "color" : [ 0, 0, 0, 128 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : 0, "y" : -1}, "color" : [ 255, 255, 255, 64 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : -1, "y" : 0}, "color" : [ 255, 255, 255, 128 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : 1, "y" : -2}, "color" : [ 255, 255, 255, 80 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : -2, "y" : 1}, "color" : [ 255, 255, 255, 160 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : -2}, "b" : { "x" : -2, "y" : -2}, "color" : [ 0, 0, 0, 192 ] },
{ "type" : "line", "a" : { "x" : -2, "y" : 1}, "b" : { "x" : -2, "y" : -2}, "color" : [ 0, 0, 0, 192 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : -1}, "b" : { "x" : -1, "y" : -1}, "color" : [ 0, 0, 0, 255 ] },
{ "type" : "line", "a" : { "x" : -1, "y" : 0}, "b" : { "x" : -1, "y" : -1}, "color" : [ 0, 0, 0, 255 ] },
]
}
]
},
"pressed" : {
"width": 25,
"height": 25,
"items" : [
{
"type": "texture",
"image": "DiBoxBck",
"color" : "blue",
"rect": {"x": 1, "y": 1, "w": 24, "h": 24}
},
{
"type": "graphicalPrimitive",
"rect": {"x": 0, "y": 0, "w": 25, "h": 25},
"primitives" : [
{ "type" : "filledBox", "a" : { "x" : 3, "y" : 3}, "b" : { "x" : -3, "y" : -3}, "color" : [ 0, 0, 0, 160 ] },
{ "type" : "rectangle", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : -1, "y" : -1}, "color" : [ 0, 0, 0, 255 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : 1, "y" : -2}, "color" : [ 255, 255, 255, 48 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : -2, "y" : 1}, "color" : [ 255, 255, 255, 96 ] },
{ "type" : "line", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : 2, "y" : -3}, "color" : [ 255, 255, 255, 64 ] },
{ "type" : "line", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : -3, "y" : 2}, "color" : [ 255, 255, 255, 128 ] },
]
}
]
},
"blocked" : {
"width": 25,
"height": 25,
"items" : [
{
"type": "texture",
"image": "DiBoxBck",
"color" : "blue",
"rect": {"x": 0, "y": 0, "w": 25, "h": 25}
},
{
"type": "graphicalPrimitive",
"rect": {"x": 0, "y": 0, "w": 25, "h": 25},
"primitives" : [
{ "type" : "filledBox", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : -3, "y" : -3}, "color" : [ 0, 0, 0, 128 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : 0, "y" : -1}, "color" : [ 255, 255, 255, 64 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : -1, "y" : 0}, "color" : [ 255, 255, 255, 128 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : 1, "y" : -2}, "color" : [ 255, 255, 255, 80 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : -2, "y" : 1}, "color" : [ 255, 255, 255, 160 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : -2}, "b" : { "x" : -2, "y" : -2}, "color" : [ 0, 0, 0, 192 ] },
{ "type" : "line", "a" : { "x" : -2, "y" : 1}, "b" : { "x" : -2, "y" : -2}, "color" : [ 0, 0, 0, 192 ] },
{ "type" : "line", "a" : { "x" : 0, "y" : -1}, "b" : { "x" : -1, "y" : -1}, "color" : [ 0, 0, 0, 255 ] },
{ "type" : "line", "a" : { "x" : -1, "y" : 0}, "b" : { "x" : -1, "y" : -1}, "color" : [ 0, 0, 0, 255 ] },
]
}
]
},
"highlighted" : {
"width": 25,
"height": 25,
"items" : [
{
"type": "texture",
"image": "DiBoxBck",
"color" : "blue",
"rect": {"x": 0, "y": 0, "w": 25, "h": 25}
},
{
"type": "graphicalPrimitive",
"rect": {"x": 0, "y": 0, "w": 25, "h": 25},
"primitives" : [
{ "type" : "filledBox", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : -3, "y" : -3}, "color" : [ 0, 0, 0, 128 ] },
{ "type" : "rectangle", "a" : { "x" : 2, "y" : 2}, "b" : { "x" : -3, "y" : -3}, "color" : [ 255, 255, 255, 255 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : -2}, "b" : { "x" : -2, "y" : -2}, "color" : [ 255, 255, 255, 255 ] },
{ "type" : "line", "a" : { "x" : -2, "y" : 1}, "b" : { "x" : -2, "y" : -2}, "color" : [ 255, 255, 255, 255 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : 1, "y" : -2}, "color" : [ 255, 255, 255, 160 ] },
{ "type" : "line", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : -2, "y" : 1}, "color" : [ 255, 255, 255, 160 ] },
]
}
]
},
}

View File

@@ -69,7 +69,7 @@
{
"type": "areaFilled",
"rect": {"x": 270, "y": 50, "w": 150, "h": 140}
"rect": {"x": 270, "y": 50, "w": 150, "h": 180}
},
{
"name" : "headerChannelList",
@@ -82,27 +82,27 @@
"itemType" : "channel",
"position" : { "x" : 272, "y" : 68 },
"itemOffset" : { "x" : 0, "y" : 40 },
"visibleAmount" : 3
"visibleAmount" : 4
},
{
"type": "areaFilled",
"rect": {"x": 270, "y": 210, "w": 150, "h": 380}
"rect": {"x": 270, "y": 250, "w": 150, "h": 340}
},
{
"name" : "headerMatchList",
"type": "labelTitle",
"position": {"x": 280, "y": 213}
"position": {"x": 280, "y": 253}
},
{
"type" : "lobbyItemList",
"name" : "matchList",
"itemType" : "match",
"position" : { "x" : 272, "y" : 228 },
"position" : { "x" : 272, "y" : 268 },
"itemOffset" : { "x" : 0, "y" : 40 },
"sliderPosition" : { "x" : 130, "y" : 0 },
"sliderSize" : { "x" : 360, "y" : 360 },
"visibleAmount" : 9
"sliderSize" : { "x" : 320, "y" : 320 },
"visibleAmount" : 8
},
{

View File

@@ -81,9 +81,11 @@ namespace RandomGeneratorUtil
for (size_t i = 0; i < container.size(); ++i)
{
roll -= container[i];
if(roll < 0)
int chance = container[i];
if(roll < chance)
return i;
roll -= chance;
}
return container.size() - 1;
}

View File

@@ -467,8 +467,7 @@ void LobbyServer::receiveRequestChatHistory(const NetworkConnectionPtr & connect
if (channelType == "global")
{
// can only be sent on connection, initiated by server
sendOperationFailed(connection, "Operation not supported!");
sendRecentChatHistory(connection, channelType, channelName);
}
if (channelType == "match")
@@ -588,6 +587,7 @@ void LobbyServer::receiveClientLogin(const NetworkConnectionPtr & connection, co
std::string accountCookie = json["accountCookie"].String();
std::string language = json["language"].String();
std::string version = json["version"].String();
const auto & languageRooms = json["languageRooms"].Vector();
if(!database->isAccountIDExists(accountID))
return sendOperationFailed(connection, "Account not found");
@@ -606,9 +606,18 @@ void LobbyServer::receiveClientLogin(const NetworkConnectionPtr & connection, co
logGlobal->info("%s: Logged in as %s", accountID, displayName);
sendClientLoginSuccess(connection, accountCookie, displayName);
sendRecentChatHistory(connection, "global", "english");
if (language != "english")
sendRecentChatHistory(connection, "global", language);
if (!languageRooms.empty())
{
for (const auto & entry : languageRooms)
sendRecentChatHistory(connection, "global", entry.String());
}
else
{
sendRecentChatHistory(connection, "global", "english");
if (language != "english")
sendRecentChatHistory(connection, "global", language);
}
// send active game rooms list to new account
// and update account list to everybody else including new account