mirror of
https://github.com/whoahq/whoa.git
synced 2026-03-19 14:11:06 +03:00
Compare commits
1 Commits
ca39b1abac
...
950f2765e3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
950f2765e3 |
@ -18,7 +18,6 @@ WowClientDB<FactionTemplateRec> g_factionTemplateDB;
|
||||
WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB;
|
||||
WowClientDB<ItemVisualsRec> g_itemVisualsDB;
|
||||
WowClientDB<MapRec> g_mapDB;
|
||||
WowClientDB<PaperDollItemFrameRec> g_paperDollItemFrameDB;
|
||||
WowClientDB<SoundEntriesRec> g_soundEntriesDB;
|
||||
WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB;
|
||||
|
||||
@ -44,7 +43,6 @@ void StaticDBLoadAll(void (*loadFn)(WowClientDB_Base*, const char*, int32_t)) {
|
||||
loadFn(&g_itemDisplayInfoDB, __FILE__, __LINE__);
|
||||
loadFn(&g_itemVisualsDB, __FILE__, __LINE__);
|
||||
loadFn(&g_mapDB, __FILE__, __LINE__);
|
||||
loadFn(&g_paperDollItemFrameDB, __FILE__, __LINE__);
|
||||
loadFn(&g_soundEntriesDB, __FILE__, __LINE__);
|
||||
loadFn(&g_soundEntriesAdvancedDB, __FILE__, __LINE__);
|
||||
};
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
#include "db/rec/ItemDisplayInfoRec.hpp"
|
||||
#include "db/rec/ItemVisualsRec.hpp"
|
||||
#include "db/rec/MapRec.hpp"
|
||||
#include "db/rec/PaperDollItemFrameRec.hpp"
|
||||
#include "db/rec/SoundEntriesRec.hpp"
|
||||
#include "db/rec/SoundEntriesAdvancedRec.hpp"
|
||||
|
||||
@ -40,7 +39,6 @@ extern WowClientDB<FactionTemplateRec> g_factionTemplateDB;
|
||||
extern WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB;
|
||||
extern WowClientDB<ItemVisualsRec> g_itemVisualsDB;
|
||||
extern WowClientDB<MapRec> g_mapDB;
|
||||
extern WowClientDB<PaperDollItemFrameRec> g_paperDollItemFrameDB;
|
||||
extern WowClientDB<SoundEntriesRec> g_soundEntriesDB;
|
||||
extern WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB;
|
||||
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
// DO NOT EDIT: generated by whoa-autocode
|
||||
#include "db/rec/PaperDollItemFrameRec.hpp"
|
||||
#include "util/Locale.hpp"
|
||||
#include "util/SFile.hpp"
|
||||
|
||||
const char* PaperDollItemFrameRec::GetFilename() {
|
||||
return "DBFilesClient\\PaperDollItemFrame.dbc";
|
||||
}
|
||||
|
||||
uint32_t PaperDollItemFrameRec::GetNumColumns() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
uint32_t PaperDollItemFrameRec::GetRowSize() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
bool PaperDollItemFrameRec::NeedIDAssigned() {
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t PaperDollItemFrameRec::GetID() {
|
||||
return this->m_generatedID;
|
||||
}
|
||||
|
||||
void PaperDollItemFrameRec::SetID(int32_t id) {
|
||||
this->m_generatedID = id;
|
||||
}
|
||||
|
||||
bool PaperDollItemFrameRec::Read(SFile* f, const char* stringBuffer) {
|
||||
uint32_t itemButtonNameOfs;
|
||||
uint32_t slotIconOfs;
|
||||
|
||||
if (
|
||||
!SFile::Read(f, &itemButtonNameOfs, sizeof(uint32_t), nullptr, nullptr, nullptr)
|
||||
|| !SFile::Read(f, &slotIconOfs, sizeof(uint32_t), nullptr, nullptr, nullptr)
|
||||
|| !SFile::Read(f, &this->m_slotNumber, sizeof(this->m_slotNumber), nullptr, nullptr, nullptr)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stringBuffer) {
|
||||
this->m_itemButtonName = &stringBuffer[itemButtonNameOfs];
|
||||
this->m_slotIcon = &stringBuffer[slotIconOfs];
|
||||
} else {
|
||||
this->m_itemButtonName = "";
|
||||
this->m_slotIcon = "";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
// DO NOT EDIT: generated by whoa-autocode
|
||||
#ifndef DB_REC_PAPER_DOLL_ITEM_FRAME_REC_HPP
|
||||
#define DB_REC_PAPER_DOLL_ITEM_FRAME_REC_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class SFile;
|
||||
|
||||
class PaperDollItemFrameRec {
|
||||
public:
|
||||
const char* m_itemButtonName;
|
||||
const char* m_slotIcon;
|
||||
int32_t m_slotNumber;
|
||||
int32_t m_generatedID;
|
||||
|
||||
static const char* GetFilename();
|
||||
static uint32_t GetNumColumns();
|
||||
static uint32_t GetRowSize();
|
||||
static bool NeedIDAssigned();
|
||||
int32_t GetID();
|
||||
void SetID(int32_t id);
|
||||
bool Read(SFile* f, const char* stringBuffer);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -17,13 +17,7 @@
|
||||
#include <cstdint>
|
||||
|
||||
int32_t Script_IsShiftKeyDown(lua_State* L) {
|
||||
if (EventIsKeyDown(KEY_LSHIFT) || EventIsKeyDown(KEY_RSHIFT)) {
|
||||
lua_pushnumber(L, 1.0);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
}
|
||||
|
||||
int32_t Script_GetBuildInfo(lua_State* L) {
|
||||
|
||||
@ -78,11 +78,6 @@ enum OUT_OF_RANGE_TYPE {
|
||||
OUT_OF_RANGE_2 = 2,
|
||||
};
|
||||
|
||||
enum PLAYER_TYPE {
|
||||
PLAYER_NORMAL = 0,
|
||||
PLAYER_BOT = 1,
|
||||
};
|
||||
|
||||
enum SHEATHE_TYPE {
|
||||
SHEATHE_0 = 0,
|
||||
SHEATHE_1 = 1,
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
#include "object/client/CGPlayer_C.hpp"
|
||||
#include "db/Db.hpp"
|
||||
#include "object/Types.hpp"
|
||||
#include "object/client/ObjMgr.hpp"
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include "ui/Game.hpp"
|
||||
#include "object/Types.hpp"
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
CGPlayer_C::CGPlayer_C(uint32_t time, CClientObjCreate& objCreate) : CGUnit_C(time, objCreate) {
|
||||
@ -36,34 +34,6 @@ void CGPlayer_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4)
|
||||
this->CGUnit_C::PostInit(time, init, a4);
|
||||
|
||||
// TODO
|
||||
|
||||
if (this->GetGUID() == ClntObjMgrGetActivePlayer()) {
|
||||
this->PostInitActivePlayer();
|
||||
} else {
|
||||
this->UpdatePartyMemberState();
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGPlayer_C::PostInitActivePlayer() {
|
||||
// TODO
|
||||
|
||||
if (ClntObjMgrGetPlayerType() == PLAYER_NORMAL) {
|
||||
// TODO
|
||||
|
||||
FrameScript_SignalEvent(SCRIPT_ACTIONBAR_SLOT_CHANGED, "%d", 0);
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
if (ClntObjMgrGetPlayerType() == PLAYER_NORMAL) {
|
||||
// TODO
|
||||
|
||||
CGGameUI::EnterWorld();
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGPlayer_C::SetStorage(uint32_t* storage, uint32_t* saved) {
|
||||
@ -73,10 +43,6 @@ void CGPlayer_C::SetStorage(uint32_t* storage, uint32_t* saved) {
|
||||
this->m_playerSaved = &saved[CGPlayer::GetBaseOffsetSaved()];
|
||||
}
|
||||
|
||||
void CGPlayer_C::UpdatePartyMemberState() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex) {
|
||||
STORM_ASSERT(sex < UNITSEX_LAST);
|
||||
|
||||
|
||||
@ -18,9 +18,7 @@ class CGPlayer_C : public CGUnit_C, public CGPlayer {
|
||||
uint32_t GetActiveNextLevelXP() const;
|
||||
uint32_t GetActiveXP() const;
|
||||
void PostInit(uint32_t time, const CClientObjCreate& init, bool a4);
|
||||
void PostInitActivePlayer();
|
||||
void SetStorage(uint32_t* storage, uint32_t* saved);
|
||||
void UpdatePartyMemberState();
|
||||
};
|
||||
|
||||
uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex);
|
||||
|
||||
@ -18,12 +18,8 @@ class ClntObjMgr {
|
||||
STORM_EXPLICIT_LIST(CGObject_C, m_link) m_reenabledObjects;
|
||||
// TODO
|
||||
WOWGUID m_activePlayer = 0;
|
||||
PLAYER_TYPE m_type;
|
||||
uint32_t m_mapID = 0;
|
||||
ClientConnection* m_net = nullptr;
|
||||
|
||||
// Member functions
|
||||
ClntObjMgr(PLAYER_TYPE type) : m_type(type) {};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -229,20 +229,3 @@ int32_t FillInPartialObjectData(CGObject_C* object, WOWGUID guid, CDataStore* ms
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t SkipPartialObjectUpdate(CDataStore* msg) {
|
||||
uint8_t changeMaskCount;
|
||||
uint32_t changeMasks[MAX_CHANGE_MASKS];
|
||||
if (!ExtractDirtyMasks(msg, &changeMaskCount, changeMasks)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int32_t block = 0; block < changeMaskCount * 32; block++) {
|
||||
if (IsMaskBitSet(changeMasks, block)) {
|
||||
uint32_t blockValue;
|
||||
msg->Get(blockValue);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -11,6 +11,4 @@ int32_t CallMirrorHandlers(CDataStore* msg, bool a2, WOWGUID guid);
|
||||
|
||||
int32_t FillInPartialObjectData(CGObject_C* object, WOWGUID guid, CDataStore* msg, bool forFullUpdate, bool zeroZeroBits);
|
||||
|
||||
int32_t SkipPartialObjectUpdate(CDataStore* msg);
|
||||
|
||||
#endif
|
||||
|
||||
@ -141,10 +141,6 @@ uint32_t ClntObjMgrGetMapID() {
|
||||
return s_curMgr->m_mapID;
|
||||
}
|
||||
|
||||
PLAYER_TYPE ClntObjMgrGetPlayerType() {
|
||||
return s_curMgr->m_type;
|
||||
}
|
||||
|
||||
void ClntObjMgrInitializeShared() {
|
||||
if (!s_heapsAllocated) {
|
||||
for (int32_t i = ID_ITEM; i < NUM_CLIENT_OBJECT_TYPES; i++) {
|
||||
@ -162,7 +158,7 @@ void ClntObjMgrInitializeShared() {
|
||||
void ClntObjMgrInitializeStd(uint32_t mapID) {
|
||||
// TODO last instance time
|
||||
|
||||
auto mgr = STORM_NEW(ClntObjMgr)(PLAYER_NORMAL);
|
||||
auto mgr = STORM_NEW(ClntObjMgr);
|
||||
|
||||
g_clientConnection->SetObjMgr(mgr);
|
||||
mgr->m_net = g_clientConnection;
|
||||
|
||||
@ -16,8 +16,6 @@ ClntObjMgr* ClntObjMgrGetCurrent();
|
||||
|
||||
uint32_t ClntObjMgrGetMapID();
|
||||
|
||||
PLAYER_TYPE ClntObjMgrGetPlayerType();
|
||||
|
||||
void ClntObjMgrInitializeShared();
|
||||
|
||||
void ClntObjMgrInitializeStd(uint32_t mapID);
|
||||
|
||||
@ -164,3 +164,8 @@ void InitObject(CGObject_C* object, uint32_t time, CClientObjCreate& objCreate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t SkipPartialObjectUpdate(CDataStore* msg) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -20,4 +20,6 @@ void HandleObjectOutOfRangePass2(CGObject_C* object);
|
||||
|
||||
void InitObject(CGObject_C* object, uint32_t time, CClientObjCreate& objCreate);
|
||||
|
||||
int32_t SkipPartialObjectUpdate(CDataStore* msg);
|
||||
|
||||
#endif
|
||||
|
||||
@ -4,6 +4,5 @@
|
||||
#include "ui/game/CGGameUI.hpp"
|
||||
#include "ui/game/CGPetInfo.hpp"
|
||||
#include "ui/game/ScriptEvents.hpp"
|
||||
#include "ui/game/Types.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#include "ui/game/CGGameUI.hpp"
|
||||
#include "client/Client.hpp"
|
||||
#include "object/Client.hpp"
|
||||
#include "ui/CScriptObject.hpp"
|
||||
#include "ui/FrameXML.hpp"
|
||||
#include "ui/Key.hpp"
|
||||
@ -18,7 +17,6 @@
|
||||
#include "ui/game/GMTicketInfoScript.hpp"
|
||||
#include "ui/game/GameScript.hpp"
|
||||
#include "ui/game/ScriptEvents.hpp"
|
||||
#include "ui/game/Types.hpp"
|
||||
#include "ui/game/UIBindingsScript.hpp"
|
||||
#include "ui/simple/CSimpleTop.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
@ -26,9 +24,7 @@
|
||||
|
||||
WOWGUID CGGameUI::s_currentObjectTrack;
|
||||
CScriptObject* CGGameUI::s_gameTooltip;
|
||||
bool CGGameUI::s_inWorld;
|
||||
WOWGUID CGGameUI::s_lockedTarget;
|
||||
bool CGGameUI::s_loggingIn;
|
||||
CSimpleTop* CGGameUI::s_simpleTop;
|
||||
|
||||
void LoadScriptFunctions() {
|
||||
@ -68,28 +64,6 @@ void LoadScriptFunctions() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGGameUI::EnterWorld() {
|
||||
if (CGGameUI::s_inWorld) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGGameUI::s_inWorld = true;
|
||||
|
||||
// TODO
|
||||
|
||||
if (CGGameUI::s_loggingIn) {
|
||||
CGGameUI::s_loggingIn = false;
|
||||
|
||||
FrameScript_SignalEvent(SCRIPT_PLAYER_LOGIN, nullptr);
|
||||
|
||||
// TODO CGLCD::Login();
|
||||
}
|
||||
|
||||
FrameScript_SignalEvent(SCRIPT_PLAYER_ENTERING_WORLD, nullptr);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
WOWGUID& CGGameUI::GetCurrentObjectTrack() {
|
||||
return CGGameUI::s_currentObjectTrack;
|
||||
}
|
||||
@ -101,10 +75,6 @@ WOWGUID& CGGameUI::GetLockedTarget() {
|
||||
void CGGameUI::Initialize() {
|
||||
// TODO
|
||||
|
||||
CGGameUI::s_loggingIn = true;
|
||||
|
||||
// TODO
|
||||
|
||||
CGGameUI::s_simpleTop = STORM_NEW(CSimpleTop);
|
||||
|
||||
// TODO
|
||||
@ -180,12 +150,6 @@ void CGGameUI::Initialize() {
|
||||
STORM_ASSERT(CGGameUI::s_gameTooltip);
|
||||
|
||||
// TODO
|
||||
|
||||
if (ClntObjMgrGetActivePlayer()) {
|
||||
CGGameUI::EnterWorld();
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGGameUI::InitializeGame() {
|
||||
@ -196,10 +160,6 @@ void CGGameUI::InitializeGame() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
bool CGGameUI::IsLoggingIn() {
|
||||
return CGGameUI::s_loggingIn;
|
||||
}
|
||||
|
||||
int32_t CGGameUI::IsRaidMember(const WOWGUID& guid) {
|
||||
// TODO
|
||||
|
||||
|
||||
@ -13,21 +13,17 @@ class CGGameUI {
|
||||
static CSimpleTop* s_simpleTop;
|
||||
|
||||
// Static functions
|
||||
static void EnterWorld();
|
||||
static WOWGUID& GetCurrentObjectTrack();
|
||||
static WOWGUID& GetLockedTarget();
|
||||
static void Initialize();
|
||||
static void InitializeGame();
|
||||
static bool IsLoggingIn();
|
||||
static int32_t IsRaidMember(const WOWGUID& guid);
|
||||
static int32_t IsRaidMemberOrPet(const WOWGUID& guid);
|
||||
static void RegisterFrameFactories();
|
||||
|
||||
private:
|
||||
static WOWGUID s_currentObjectTrack;
|
||||
static bool s_inWorld;
|
||||
static WOWGUID s_lockedTarget;
|
||||
static bool s_loggingIn;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,48 +1,11 @@
|
||||
#include "ui/game/CharacterInfoScript.hpp"
|
||||
#include "db/Db.hpp"
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
int32_t Script_GetInventorySlotInfo(lua_State* L) {
|
||||
if (!lua_isstring(L, 1)) {
|
||||
luaL_error(L, "Invalid inventory slot in GetInventorySlotInfo");
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto slotName = lua_tostring(L, 1);
|
||||
|
||||
PaperDollItemFrameRec* slotRec = nullptr;
|
||||
for (int32_t i = 0; i < g_paperDollItemFrameDB.GetNumRecords(); i++) {
|
||||
auto paperDollItemFrameRec = g_paperDollItemFrameDB.GetRecordByIndex(i);
|
||||
|
||||
if (paperDollItemFrameRec && !SStrCmpI(slotName, paperDollItemFrameRec->m_itemButtonName)) {
|
||||
slotRec = paperDollItemFrameRec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!slotRec) {
|
||||
luaL_error(L, "Invalid inventory slot in GetInventorySlotInfo");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// id
|
||||
lua_pushnumber(L, slotRec->m_slotNumber);
|
||||
|
||||
// textureName
|
||||
lua_pushstring(L, slotRec->m_slotIcon);
|
||||
|
||||
// checkRelic
|
||||
if (slotRec->m_slotNumber == EQUIPPED_LAST) {
|
||||
lua_pushnumber(L, 1.0);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 3;
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
}
|
||||
|
||||
int32_t Script_GetInventoryItemsForSlot(lua_State* L) {
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
#include "ui/ScriptFunctionsSystem.hpp"
|
||||
#include "ui/game/CGGameUI.hpp"
|
||||
#include "ui/game/ScriptUtil.hpp"
|
||||
#include "ui/game/Types.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/StringTo.hpp"
|
||||
@ -1057,7 +1056,7 @@ void ScriptEventsInitialize() {
|
||||
g_scriptEvents[173] = "ACTIONBAR_SHOWGRID";
|
||||
g_scriptEvents[174] = "ACTIONBAR_HIDEGRID";
|
||||
g_scriptEvents[175] = "ACTIONBAR_PAGE_CHANGED";
|
||||
g_scriptEvents[SCRIPT_ACTIONBAR_SLOT_CHANGED] = "ACTIONBAR_SLOT_CHANGED";
|
||||
g_scriptEvents[176] = "ACTIONBAR_SLOT_CHANGED";
|
||||
g_scriptEvents[177] = "ACTIONBAR_UPDATE_STATE";
|
||||
g_scriptEvents[178] = "ACTIONBAR_UPDATE_USABLE";
|
||||
g_scriptEvents[179] = "ACTIONBAR_UPDATE_COOLDOWN";
|
||||
@ -1134,9 +1133,9 @@ void ScriptEventsInitialize() {
|
||||
g_scriptEvents[250] = "LOOT_SLOT_CLEARED";
|
||||
g_scriptEvents[251] = "LOOT_SLOT_CHANGED";
|
||||
g_scriptEvents[252] = "LOOT_CLOSED";
|
||||
g_scriptEvents[SCRIPT_PLAYER_LOGIN] = "PLAYER_LOGIN";
|
||||
g_scriptEvents[SCRIPT_PLAYER_LOGOUT] = "PLAYER_LOGOUT";
|
||||
g_scriptEvents[SCRIPT_PLAYER_ENTERING_WORLD] = "PLAYER_ENTERING_WORLD";
|
||||
g_scriptEvents[253] = "PLAYER_LOGIN";
|
||||
g_scriptEvents[254] = "PLAYER_LOGOUT";
|
||||
g_scriptEvents[255] = "PLAYER_ENTERING_WORLD";
|
||||
g_scriptEvents[256] = "PLAYER_LEAVING_WORLD";
|
||||
g_scriptEvents[257] = "PLAYER_ALIVE";
|
||||
g_scriptEvents[258] = "PLAYER_DEAD";
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
#ifndef UI_GAME_TYPES_HPP
|
||||
#define UI_GAME_TYPES_HPP
|
||||
|
||||
enum SCRIPTEVENT {
|
||||
// TODO
|
||||
SCRIPT_ACTIONBAR_SLOT_CHANGED = 176,
|
||||
// TODO
|
||||
SCRIPT_PLAYER_LOGIN = 253,
|
||||
SCRIPT_PLAYER_LOGOUT = 254,
|
||||
SCRIPT_PLAYER_ENTERING_WORLD = 255,
|
||||
// TODO
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user