Implemented DisconnectedScreen, and removed CharacterMap
Project also builds, since I went through and adjusted it. It's hacky right now, but I just want to make sure it worked. I'll give it another pass before merging into develop.
This commit is contained in:
@@ -38,8 +38,7 @@
|
|||||||
#include "options_menu.hpp"
|
#include "options_menu.hpp"
|
||||||
#include "lobby_menu.hpp"
|
#include "lobby_menu.hpp"
|
||||||
#include "in_world.hpp"
|
#include "in_world.hpp"
|
||||||
//#include "in_combat.hpp"
|
#include "disconnected_screen.hpp"
|
||||||
#include "clean_up.hpp"
|
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Public access members
|
//Public access members
|
||||||
@@ -179,16 +178,13 @@ void ClientApplication::LoadScene(SceneList sceneIndex) {
|
|||||||
activeScene = new OptionsMenu();
|
activeScene = new OptionsMenu();
|
||||||
break;
|
break;
|
||||||
case SceneList::LOBBYMENU:
|
case SceneList::LOBBYMENU:
|
||||||
activeScene = new LobbyMenu(&clientIndex, &accountIndex);
|
activeScene = new LobbyMenu(&clientIndex, &accountIndex); //TODO: can I use the ConfigUtility for these parameters?
|
||||||
break;
|
break;
|
||||||
case SceneList::INWORLD:
|
case SceneList::INWORLD:
|
||||||
activeScene = new InWorld(&clientIndex, &accountIndex, &characterIndex, &characterMap);
|
activeScene = new InWorld(&clientIndex, &accountIndex);
|
||||||
break;
|
break;
|
||||||
// case SceneList::INCOMBAT:
|
case SceneList::DISCONNECTEDSCREEN:
|
||||||
// activeScene = new InCombat(&clientIndex, &accountIndex, &characterIndex, &characterMap);
|
activeScene = new DisconnectedScreen();
|
||||||
// break;
|
|
||||||
case SceneList::CLEANUP:
|
|
||||||
activeScene = new CleanUp(&clientIndex, &accountIndex, &characterIndex, &characterMap);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw(std::logic_error("Failed to recognize the scene index"));
|
throw(std::logic_error("Failed to recognize the scene index"));
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
#include "base_scene.hpp"
|
#include "base_scene.hpp"
|
||||||
|
|
||||||
#include "udp_network_utility.hpp"
|
#include "udp_network_utility.hpp"
|
||||||
#include "character.hpp"
|
|
||||||
|
|
||||||
#include "singleton.hpp"
|
#include "singleton.hpp"
|
||||||
|
|
||||||
@@ -54,9 +53,6 @@ private:
|
|||||||
//shared parameters
|
//shared parameters
|
||||||
int clientIndex = -1;
|
int clientIndex = -1;
|
||||||
int accountIndex = -1;
|
int accountIndex = -1;
|
||||||
int characterIndex = -1;
|
|
||||||
|
|
||||||
CharacterMap characterMap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,5 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. client_utilities scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet_types ../common/ui ../common/utilities
|
INCLUDES+=. client_utilities renderable scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet_types ../common/ui ../common/utilities
|
||||||
LIBS+=client.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua
|
LIBS+=client.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
@@ -18,6 +18,7 @@ OUT=$(addprefix $(OUTDIR)/,client)
|
|||||||
all: $(OBJ) $(OUT)
|
all: $(OBJ) $(OUT)
|
||||||
$(MAKE) -C client_utilities
|
$(MAKE) -C client_utilities
|
||||||
$(MAKE) -C scenes
|
$(MAKE) -C scenes
|
||||||
|
$(MAKE) -C renderable
|
||||||
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
||||||
|
|
||||||
$(OBJ): | $(OBJDIR)
|
$(OBJ): | $(OBJDIR)
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ enum class SceneList {
|
|||||||
OPTIONSMENU,
|
OPTIONSMENU,
|
||||||
LOBBYMENU,
|
LOBBYMENU,
|
||||||
INWORLD,
|
INWORLD,
|
||||||
INCOMBAT,
|
DISCONNECTEDSCREEN,
|
||||||
CLEANUP,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -19,10 +19,11 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#include "clean_up.hpp"
|
#include "disconnected_screen.hpp"
|
||||||
|
|
||||||
#include "channels.hpp"
|
#include "channels.hpp"
|
||||||
#include "config_utility.hpp"
|
#include "config_utility.hpp"
|
||||||
|
#include "udp_network_utility.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
@@ -30,17 +31,7 @@
|
|||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
CleanUp::CleanUp(
|
DisconnectedScreen::DisconnectedScreen() {
|
||||||
int* const argClientIndex,
|
|
||||||
int* const argAccountIndex,
|
|
||||||
int* const argCharacterIndex,
|
|
||||||
CharacterMap* argCharacterMap
|
|
||||||
):
|
|
||||||
clientIndex(*argClientIndex),
|
|
||||||
accountIndex(*argAccountIndex),
|
|
||||||
characterIndex(*argCharacterIndex),
|
|
||||||
characterMap(*argCharacterMap)
|
|
||||||
{
|
|
||||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||||
|
|
||||||
//setup the utility objects
|
//setup the utility objects
|
||||||
@@ -60,19 +51,13 @@ CleanUp::CleanUp(
|
|||||||
backButton.SetText("Back");
|
backButton.SetText("Back");
|
||||||
|
|
||||||
//full reset
|
//full reset
|
||||||
network.Unbind(Channels::SERVER);
|
UDPNetworkUtility::GetSingleton().Unbind(Channels::SERVER);
|
||||||
clientIndex = -1;
|
|
||||||
accountIndex = -1;
|
|
||||||
characterIndex = -1;
|
|
||||||
// combatMap.clear();
|
|
||||||
characterMap.clear();
|
|
||||||
// enemyMap.clear();
|
|
||||||
|
|
||||||
//auto return
|
//auto return
|
||||||
startTick = std::chrono::steady_clock::now();
|
startTick = std::chrono::steady_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
CleanUp::~CleanUp() {
|
DisconnectedScreen::~DisconnectedScreen() {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,16 +65,16 @@ CleanUp::~CleanUp() {
|
|||||||
//Frame loop
|
//Frame loop
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void CleanUp::Update() {
|
void DisconnectedScreen::Update() {
|
||||||
if (std::chrono::steady_clock::now() - startTick > std::chrono::duration<int>(10)) {
|
if (std::chrono::steady_clock::now() - startTick > std::chrono::duration<int>(10)) {
|
||||||
SetNextScene(SceneList::MAINMENU);
|
SetNextScene(SceneList::MAINMENU);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Eat incoming packets
|
//Eat incoming packets
|
||||||
while(network.Receive());
|
while(UDPNetworkUtility::GetSingleton().Receive());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanUp::Render(SDL_Surface* const screen) {
|
void DisconnectedScreen::Render(SDL_Surface* const screen) {
|
||||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||||
|
|
||||||
backButton.DrawTo(screen);
|
backButton.DrawTo(screen);
|
||||||
@@ -100,25 +85,25 @@ void CleanUp::Render(SDL_Surface* const screen) {
|
|||||||
//Event handlers
|
//Event handlers
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void CleanUp::QuitEvent() {
|
void DisconnectedScreen::QuitEvent() {
|
||||||
SetNextScene(SceneList::QUIT);
|
SetNextScene(SceneList::QUIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanUp::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
void DisconnectedScreen::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
||||||
backButton.MouseMotion(motion);
|
backButton.MouseMotion(motion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanUp::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
void DisconnectedScreen::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
||||||
backButton.MouseButtonDown(button);
|
backButton.MouseButtonDown(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanUp::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
void DisconnectedScreen::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
||||||
if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
|
if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
|
||||||
SetNextScene(SceneList::MAINMENU);
|
SetNextScene(SceneList::MAINMENU);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanUp::KeyDown(SDL_KeyboardEvent const& key) {
|
void DisconnectedScreen::KeyDown(SDL_KeyboardEvent const& key) {
|
||||||
switch(key.keysym.sym) {
|
switch(key.keysym.sym) {
|
||||||
case SDLK_ESCAPE:
|
case SDLK_ESCAPE:
|
||||||
SetNextScene(SceneList::MAINMENU);
|
SetNextScene(SceneList::MAINMENU);
|
||||||
@@ -126,6 +111,6 @@ void CleanUp::KeyDown(SDL_KeyboardEvent const& key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanUp::KeyUp(SDL_KeyboardEvent const& key) {
|
void DisconnectedScreen::KeyUp(SDL_KeyboardEvent const& key) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,8 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#ifndef CLEANUP_HPP_
|
#ifndef DISCONNECTEDSCREEN_HPP_
|
||||||
#define CLEANUP_HPP_
|
#define DISCONNECTEDSCREEN_HPP_
|
||||||
|
|
||||||
//network
|
|
||||||
#include "udp_network_utility.hpp"
|
|
||||||
|
|
||||||
//graphics
|
//graphics
|
||||||
#include "image.hpp"
|
#include "image.hpp"
|
||||||
@@ -31,22 +28,16 @@
|
|||||||
#include "button.hpp"
|
#include "button.hpp"
|
||||||
|
|
||||||
//client
|
//client
|
||||||
#include "character.hpp"
|
|
||||||
#include "base_scene.hpp"
|
#include "base_scene.hpp"
|
||||||
|
|
||||||
//std namespace
|
//std namespace
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
class CleanUp : public BaseScene {
|
class DisconnectedScreen : public BaseScene {
|
||||||
public:
|
public:
|
||||||
//Public access members
|
//Public access members
|
||||||
CleanUp(
|
DisconnectedScreen();
|
||||||
int* const argClientIndex,
|
~DisconnectedScreen();
|
||||||
int* const argAccountIndex,
|
|
||||||
int* const argCharacterIndex,
|
|
||||||
CharacterMap* argCharacterMap
|
|
||||||
);
|
|
||||||
~CleanUp();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//Frame loop
|
//Frame loop
|
||||||
@@ -61,13 +52,6 @@ protected:
|
|||||||
void KeyDown(SDL_KeyboardEvent const&);
|
void KeyDown(SDL_KeyboardEvent const&);
|
||||||
void KeyUp(SDL_KeyboardEvent const&);
|
void KeyUp(SDL_KeyboardEvent const&);
|
||||||
|
|
||||||
//shared parameters
|
|
||||||
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
|
|
||||||
int& clientIndex;
|
|
||||||
int& accountIndex;
|
|
||||||
int& characterIndex;
|
|
||||||
CharacterMap& characterMap;
|
|
||||||
|
|
||||||
//graphics
|
//graphics
|
||||||
Image image;
|
Image image;
|
||||||
RasterFont font;
|
RasterFont font;
|
||||||
|
|||||||
@@ -34,16 +34,9 @@
|
|||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
InWorld::InWorld(
|
InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex):
|
||||||
int* const argClientIndex,
|
|
||||||
int* const argAccountIndex,
|
|
||||||
int* const argCharacterIndex,
|
|
||||||
CharacterMap* argCharacterMap
|
|
||||||
):
|
|
||||||
clientIndex(*argClientIndex),
|
clientIndex(*argClientIndex),
|
||||||
accountIndex(*argAccountIndex),
|
accountIndex(*argAccountIndex)
|
||||||
characterIndex(*argCharacterIndex),
|
|
||||||
characterMap(*argCharacterMap)
|
|
||||||
{
|
{
|
||||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||||
|
|
||||||
@@ -153,7 +146,7 @@ void InWorld::Update() {
|
|||||||
if (Clock::now() - lastBeat > std::chrono::seconds(3)) {
|
if (Clock::now() - lastBeat > std::chrono::seconds(3)) {
|
||||||
if (attemptedBeats > 2) {
|
if (attemptedBeats > 2) {
|
||||||
RequestDisconnect();
|
RequestDisconnect();
|
||||||
SetNextScene(SceneList::CLEANUP);
|
SetNextScene(SceneList::DISCONNECTEDSCREEN);
|
||||||
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server";
|
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +335,7 @@ void InWorld::HandlePong(ServerPacket* const argPacket) {
|
|||||||
|
|
||||||
void InWorld::HandleDisconnect(ClientPacket* const argPacket) {
|
void InWorld::HandleDisconnect(ClientPacket* const argPacket) {
|
||||||
//TODO: More needed in the disconnection
|
//TODO: More needed in the disconnection
|
||||||
SetNextScene(SceneList::CLEANUP);
|
SetNextScene(SceneList::DISCONNECTEDSCREEN);
|
||||||
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have been disconnected";
|
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have been disconnected";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +345,7 @@ void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//create the character object
|
//create the character object
|
||||||
Character& newCharacter = characterMap[argPacket->characterIndex];
|
BaseCharacter& newCharacter = characterMap[argPacket->characterIndex];
|
||||||
|
|
||||||
//fill out the character's members
|
//fill out the character's members
|
||||||
newCharacter.SetHandle(argPacket->handle);
|
newCharacter.SetHandle(argPacket->handle);
|
||||||
@@ -369,7 +362,7 @@ void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) {
|
|||||||
CHARACTER_BOUNDS_HEIGHT
|
CHARACTER_BOUNDS_HEIGHT
|
||||||
});
|
});
|
||||||
|
|
||||||
(*newCharacter.GetStats()) = argPacket->stats;
|
// (*newCharacter.GetBaseStats()) = argPacket->stats;
|
||||||
|
|
||||||
//bookkeeping code
|
//bookkeeping code
|
||||||
newCharacter.CorrectSprite();
|
newCharacter.CorrectSprite();
|
||||||
@@ -407,7 +400,7 @@ void InWorld::HandleCharacterUpdate(CharacterPacket* const argPacket) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Character& character = characterMap[argPacket->characterIndex];
|
BaseCharacter& character = characterMap[argPacket->characterIndex];
|
||||||
|
|
||||||
//other characters moving
|
//other characters moving
|
||||||
if (argPacket->characterIndex != characterIndex) {
|
if (argPacket->characterIndex != characterIndex) {
|
||||||
@@ -419,7 +412,7 @@ void InWorld::HandleCharacterUpdate(CharacterPacket* const argPacket) {
|
|||||||
|
|
||||||
void InWorld::HandleCharacterRejection(TextPacket* const argPacket) {
|
void InWorld::HandleCharacterRejection(TextPacket* const argPacket) {
|
||||||
RequestDisconnect();
|
RequestDisconnect();
|
||||||
SetNextScene(SceneList::CLEANUP);
|
SetNextScene(SceneList::DISCONNECTEDSCREEN);
|
||||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||||
config["client.disconnectMessage"] = "Error: ";
|
config["client.disconnectMessage"] = "Error: ";
|
||||||
config["client.disconnectMessage"] += argPacket->text;
|
config["client.disconnectMessage"] += argPacket->text;
|
||||||
@@ -464,7 +457,7 @@ void InWorld::SendPlayerUpdate() {
|
|||||||
newPacket.roomIndex = 0; //TODO: room index
|
newPacket.roomIndex = 0; //TODO: room index
|
||||||
newPacket.origin = localCharacter->GetOrigin();
|
newPacket.origin = localCharacter->GetOrigin();
|
||||||
newPacket.motion = localCharacter->GetMotion();
|
newPacket.motion = localCharacter->GetMotion();
|
||||||
newPacket.stats = *localCharacter->GetStats();
|
// newPacket.stats = *localCharacter->GetBaseStats();
|
||||||
|
|
||||||
//TODO: gameplay components: equipment, items, buffs, debuffs
|
//TODO: gameplay components: equipment, items, buffs, debuffs
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,8 @@
|
|||||||
//common
|
//common
|
||||||
#include "frame_rate.hpp"
|
#include "frame_rate.hpp"
|
||||||
|
|
||||||
#include "character.hpp"
|
#include "base_character.hpp"
|
||||||
|
#include "local_character.hpp"
|
||||||
|
|
||||||
//client
|
//client
|
||||||
#include "base_scene.hpp"
|
#include "base_scene.hpp"
|
||||||
@@ -51,12 +52,7 @@
|
|||||||
class InWorld : public BaseScene {
|
class InWorld : public BaseScene {
|
||||||
public:
|
public:
|
||||||
//Public access members
|
//Public access members
|
||||||
InWorld(
|
InWorld(int* const argClientIndex, int* const argAccountIndex);
|
||||||
int* const argClientIndex,
|
|
||||||
int* const argAccountIndex,
|
|
||||||
int* const argCharacterIndex,
|
|
||||||
CharacterMap* argCharacterMap
|
|
||||||
);
|
|
||||||
~InWorld();
|
~InWorld();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -100,8 +96,8 @@ protected:
|
|||||||
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
|
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
|
||||||
int& clientIndex;
|
int& clientIndex;
|
||||||
int& accountIndex;
|
int& accountIndex;
|
||||||
int& characterIndex;
|
int characterIndex = -1;
|
||||||
CharacterMap& characterMap;
|
std::map<int, BaseCharacter> characterMap;
|
||||||
|
|
||||||
//graphics
|
//graphics
|
||||||
Image buttonImage;
|
Image buttonImage;
|
||||||
@@ -124,7 +120,7 @@ protected:
|
|||||||
FrameRate fps;
|
FrameRate fps;
|
||||||
|
|
||||||
//game
|
//game
|
||||||
Character* localCharacter = nullptr;
|
BaseCharacter* localCharacter = nullptr;
|
||||||
|
|
||||||
//connections
|
//connections
|
||||||
//TODO: This needs it's own utility, for both InWorld and InCombat
|
//TODO: This needs it's own utility, for both InWorld and InCombat
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ LobbyMenu::LobbyMenu(int* const argClientIndex, int* const argAccountIndex):
|
|||||||
clientIndex(*argClientIndex),
|
clientIndex(*argClientIndex),
|
||||||
accountIndex(*argAccountIndex)
|
accountIndex(*argAccountIndex)
|
||||||
{
|
{
|
||||||
|
//preemptive reset
|
||||||
|
clientIndex = -1;
|
||||||
|
accountIndex = -1;
|
||||||
|
|
||||||
//setup the utility objects
|
//setup the utility objects
|
||||||
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
||||||
image.SetClipH(image.GetClipH()/3);
|
image.SetClipH(image.GetClipH()/3);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. .. ../../common/gameplay ../../common/graphics ../../common/map ../../common/network ../../common/network/packet_types ../../common/ui ../../common/utilities
|
INCLUDES+=. .. ../renderable ../../common/gameplay ../../common/graphics ../../common/map ../../common/network ../../common/network/packet_types ../../common/ui ../../common/utilities
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user