Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Krasheninnikov <boba09@list.ru>2025-02-08 20:40:33 +0100
committerVladimir Krasheninnikov <boba09@list.ru>2025-02-08 20:40:33 +0100
commit0d860dc2e3832d5cb460e4d474b7e08c090a791a (patch)
tree1923174c217f39ad11451dc8f18961e4785dd068
parent4244b60fd27122368d6a685199ddf325dfdd1c2e (diff)
Search character by name
-rw-r--r--assets/opensb/interface/windowconfig/charselection.config.patch18
-rw-r--r--source/frontend/StarCharSelection.cpp27
-rw-r--r--source/frontend/StarCharSelection.hpp2
-rw-r--r--source/game/StarPlayerStorage.cpp21
-rw-r--r--source/game/StarPlayerStorage.hpp2
5 files changed, 57 insertions, 13 deletions
diff --git a/assets/opensb/interface/windowconfig/charselection.config.patch b/assets/opensb/interface/windowconfig/charselection.config.patch
index c904b44..bc6bffa 100644
--- a/assets/opensb/interface/windowconfig/charselection.config.patch
+++ b/assets/opensb/interface/windowconfig/charselection.config.patch
@@ -1,9 +1,15 @@
{
- "createCharButton" : {
- "type" : "button",
- "base" : "/interface/title/createcharacter.png",
- "hover" : "/interface/title/createcharacterover.png",
- "position" : [23, 241],
- "pressedOffset" : [0, 0]
+ "createCharButton": {
+ "type": "button",
+ "base": "/interface/title/createcharacter.png",
+ "hover": "/interface/title/createcharacterover.png",
+ "position": [ 23, 241 ],
+ "pressedOffset": [ 0, 0 ]
+ },
+ "searchCharacter": {
+ "type": "textbox",
+ "hint": "Search...",
+ "position": [ 130, 244 ],
+ "maxWidth": 75
}
}
diff --git a/source/frontend/StarCharSelection.cpp b/source/frontend/StarCharSelection.cpp
index 4c56d59..2bf4f93 100644
--- a/source/frontend/StarCharSelection.cpp
+++ b/source/frontend/StarCharSelection.cpp
@@ -2,6 +2,7 @@
#include "StarGuiReader.hpp"
#include "StarRoot.hpp"
#include "StarLargeCharPlateWidget.hpp"
+#include "StarTextBoxWidget.hpp"
#include "StarAssets.hpp"
#include "StarRandom.hpp"
#include "StarInputEvent.hpp"
@@ -14,6 +15,8 @@ CharSelectionPane::CharSelectionPane(PlayerStoragePtr playerStorage,
DeleteCharacterCallback deleteCallback)
: m_playerStorage(playerStorage),
m_downScroll(0),
+ m_filteredList({}),
+ m_search(""),
m_createCallback(createCallback),
m_selectCallback(selectCallback),
m_deleteCallback(deleteCallback) {
@@ -28,6 +31,11 @@ CharSelectionPane::CharSelectionPane(PlayerStoragePtr playerStorage,
guiReader.registerCallback("charSelector3", [=](Widget*) { selectCharacter(2); });
guiReader.registerCallback("charSelector4", [=](Widget*) { selectCharacter(3); });
guiReader.registerCallback("createCharButton", [=](Widget*) { m_createCallback(); });
+ guiReader.registerCallback("searchCharacter", [=](Widget* obj) {
+ m_downScroll = 0;
+ m_search = convert<TextBoxWidget>(obj)->getText().trim().toLower();
+ updateCharacterPlates();
+ });
guiReader.construct(root.assets()->json("/interface/windowconfig/charselection.config"), this);
}
@@ -55,13 +63,14 @@ void CharSelectionPane::show() {
}
void CharSelectionPane::shiftCharacters(int shift) {
- m_downScroll = std::max<int>(std::min<int>(m_downScroll + shift, m_playerStorage->playerCount() - 3), 0);
+ m_downScroll = std::max<int>(std::min<int>(m_downScroll + shift, m_filteredList.size() - 3), 0);
updateCharacterPlates();
}
void CharSelectionPane::selectCharacter(unsigned buttonIndex) {
- if (auto playerUuid = m_playerStorage->playerUuidAt(m_downScroll + buttonIndex)) {
- auto player = m_playerStorage->loadPlayer(*playerUuid);
+ if (m_downScroll + buttonIndex < m_filteredList.size()) {
+ auto playerUuid = m_filteredList.get(m_downScroll + buttonIndex);
+ auto player = m_playerStorage->loadPlayer(playerUuid);
if (player->isPermaDead() && !player->isAdmin()) {
auto sound = Random::randValueFrom(
Root::singleton().assets()->json("/interface.config:buttonClickFailSound").toArray(), "")
@@ -75,13 +84,17 @@ void CharSelectionPane::selectCharacter(unsigned buttonIndex) {
}
void CharSelectionPane::updateCharacterPlates() {
+
auto updatePlayerLine = [this](String name, unsigned scrollPosition) {
+ m_filteredList = m_playerStorage->playerUuidListByName(m_search);
auto charSelector = fetchChild<LargeCharPlateWidget>(name);
- if (auto playerUuid = m_playerStorage->playerUuidAt(scrollPosition)) {
- if (auto player = m_playerStorage->loadPlayer(*playerUuid)) {
+
+ if (m_filteredList.size() > 0 && scrollPosition < m_filteredList.size()) {
+ auto playerUuid = m_filteredList.get(scrollPosition);
+ if (auto player = m_playerStorage->loadPlayer(playerUuid)) {
player->humanoid()->setFacingDirection(Direction::Right);
charSelector->setPlayer(player);
- charSelector->enableDelete([this, playerUuid](Widget*) { m_deleteCallback(*playerUuid); });
+ charSelector->enableDelete([this, playerUuid](Widget*) { m_deleteCallback(playerUuid); });
return;
}
}
@@ -99,7 +112,7 @@ void CharSelectionPane::updateCharacterPlates() {
else
fetchChild("playerUpButton")->hide();
- if (m_downScroll < m_playerStorage->playerCount() - 3)
+ if (m_downScroll < m_filteredList.size() - 3)
fetchChild("playerDownButton")->show();
else
fetchChild("playerDownButton")->hide();
diff --git a/source/frontend/StarCharSelection.hpp b/source/frontend/StarCharSelection.hpp
index 64e1343..b4837ca 100644
--- a/source/frontend/StarCharSelection.hpp
+++ b/source/frontend/StarCharSelection.hpp
@@ -26,6 +26,8 @@ private:
PlayerStoragePtr m_playerStorage;
unsigned m_downScroll;
+ String m_search;
+ List<Uuid> m_filteredList;
CreateCharCallback m_createCallback;
SelectCharacterCallback m_selectCallback;
diff --git a/source/game/StarPlayerStorage.cpp b/source/game/StarPlayerStorage.cpp
index 7857f8d..bba080e 100644
--- a/source/game/StarPlayerStorage.cpp
+++ b/source/game/StarPlayerStorage.cpp
@@ -132,6 +132,27 @@ Maybe<Uuid> PlayerStorage::playerUuidByName(String const& name, Maybe<Uuid> exce
return uuid;
}
+List<Uuid> PlayerStorage::playerUuidListByName(String const& name, Maybe<Uuid> except) {
+ String cleanMatch = Text::stripEscapeCodes(name).toLower();
+ List<Uuid> list = {};
+
+ RecursiveMutexLocker locker(m_mutex);
+
+ for (auto& cache : m_savedPlayersCache) {
+ if (except && *except == cache.first)
+ continue;
+ else if (auto name = cache.second.optQueryString("identity.name")) {
+ auto cleanName = Text::stripEscapeCodes(*name).toLower();
+ if (cleanMatch == "" || cleanName.utf8().rfind(cleanMatch.utf8()) != NPos) {
+ list.append(cache.first);
+ }
+ }
+ }
+
+ return list;
+}
+
+
Json PlayerStorage::savePlayer(PlayerPtr const& player) {
auto entityFactory = Root::singleton().entityFactory();
auto versioningDatabase = Root::singleton().versioningDatabase();
diff --git a/source/game/StarPlayerStorage.hpp b/source/game/StarPlayerStorage.hpp
index c9bc2d8..4033dae 100644
--- a/source/game/StarPlayerStorage.hpp
+++ b/source/game/StarPlayerStorage.hpp
@@ -19,6 +19,8 @@ public:
Maybe<Uuid> playerUuidAt(size_t index);
// Returns nothing if name doesn't match a player.
Maybe<Uuid> playerUuidByName(String const& name, Maybe<Uuid> except = {});
+ // Returns nothing if name doesn't match a player.
+ List<Uuid> playerUuidListByName(String const& name, Maybe<Uuid> except = {});
// Also returns the diskStore Json if needed.
Json savePlayer(PlayerPtr const& player);