Browse Source

Code cleanups. Eric sucks.

Adam Johnson 14 years ago
parent
commit
7cf30f8fc7
  1. 4
      Sources/Plasma/FeatureLib/pfPython/pyVault.cpp
  2. 154
      Sources/Plasma/PubUtilLib/plNetClient/plNetLinkingMgr.cpp

4
Sources/Plasma/FeatureLib/pfPython/pyVault.cpp

@ -60,10 +60,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plSDL/plSDL.h" #include "plSDL/plSDL.h"
#include <stdlib.h>
#include <string.h>
//============================================================================ //============================================================================
static PyObject * GetFolder (unsigned folderType) { static PyObject * GetFolder (unsigned folderType) {
PyObject * result = nil; PyObject * result = nil;

154
Sources/Plasma/PubUtilLib/plNetClient/plNetLinkingMgr.cpp

@ -512,7 +512,7 @@ void plNetLinkingMgr::LinkToMyPersonalAge( UInt32 playerID )
hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. Linking is disabled." ) ); hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. Linking is disabled." ) );
return; return;
} }
plNetClientMgr * nc = plNetClientMgr::GetInstance(); plNetClientMgr* nc = plNetClientMgr::GetInstance();
plAgeLinkStruct link; plAgeLinkStruct link;
link.GetAgeInfo()->SetAgeFilename( kPersonalAgeFilename ); link.GetAgeInfo()->SetAgeFilename( kPersonalAgeFilename );
@ -665,23 +665,27 @@ void plNetLinkingMgr::OfferLinkToPlayer( const plAgeInfoStruct * inInfo, UInt32
void plNetLinkingMgr::IPostProcessLink( void ) void plNetLinkingMgr::IPostProcessLink( void )
{ {
bool city = (0 == stricmp( GetAgeLink()->GetAgeInfo()->GetAgeFilename(), kCityAgeFilename )); // Grab some useful things...
bool hood = (0 == stricmp( GetAgeLink()->GetAgeInfo()->GetAgeFilename(), kNeighborhoodAgeFilename )); plAgeLinkStruct* link = GetAgeLink();
bool psnl = (0 == stricmp( GetAgeLink()->GetAgeInfo()->GetAgeFilename(), kPersonalAgeFilename )); plAgeInfoStruct* info = link->GetAgeInfo();
bool city = (stricmp(info->GetAgeFilename(), kCityAgeFilename) == 0);
bool hood = (stricmp(info->GetAgeFilename(), kNeighborhoodAgeFilename) == 0);
bool psnl = (stricmp(info->GetAgeFilename(), kPersonalAgeFilename) == 0);
// Update our online status // Update our online status
if (RelVaultNode * rvnInfo = VaultGetPlayerInfoNodeIncRef()) { if (RelVaultNode* rvnInfo = VaultGetPlayerInfoNodeIncRef()) {
VaultPlayerInfoNode accInfo(rvnInfo); VaultPlayerInfoNode accInfo(rvnInfo);
wchar ageInstName[MAX_PATH]; wchar ageInstName[MAX_PATH];
Uuid ageInstGuid = *GetAgeLink()->GetAgeInfo()->GetAgeInstanceGuid(); Uuid ageInstGuid = *info->GetAgeInstanceGuid();
StrToUnicode(ageInstName, GetAgeLink()->GetAgeInfo()->GetAgeInstanceName(), arrsize(ageInstName)); StrToUnicode(ageInstName, info->GetAgeInstanceName(), arrsize(ageInstName));
accInfo.SetAgeInstName(ageInstName); accInfo.SetAgeInstName(ageInstName);
accInfo.SetAgeInstUuid(ageInstGuid); accInfo.SetAgeInstUuid(ageInstGuid);
accInfo.SetOnline(true); accInfo.SetOnline(true);
rvnInfo->DecRef(); rvnInfo->DecRef();
} }
switch (GetAgeLink()->GetLinkingRules()) { switch (link->GetLinkingRules()) {
case plNetCommon::LinkingRules::kOwnedBook: { case plNetCommon::LinkingRules::kOwnedBook: {
// SPECIAL CASE: City: Every player ever created would be in the list; avoid that. // SPECIAL CASE: City: Every player ever created would be in the list; avoid that.
@ -689,8 +693,8 @@ void plNetLinkingMgr::IPostProcessLink( void )
break; break;
{ // Ensure we're in the AgeOwners folder { // Ensure we're in the AgeOwners folder
RelVaultNode * fldr = VaultGetAgeAgeOwnersFolderIncRef(); RelVaultNode* fldr = VaultGetAgeAgeOwnersFolderIncRef();
RelVaultNode * info = VaultGetPlayerInfoNodeIncRef(); RelVaultNode* info = VaultGetPlayerInfoNodeIncRef();
if (fldr && info) if (fldr && info)
if (!fldr->IsParentOf(info->nodeId, 1)) if (!fldr->IsParentOf(info->nodeId, 1))
@ -714,8 +718,8 @@ void plNetLinkingMgr::IPostProcessLink( void )
break; break;
{ // Ensure we're in the CanVisit folder { // Ensure we're in the CanVisit folder
RelVaultNode * fldr = VaultGetAgeCanVisitFolderIncRef(); RelVaultNode* fldr = VaultGetAgeCanVisitFolderIncRef();
RelVaultNode * info = VaultGetPlayerInfoNodeIncRef(); RelVaultNode* info = VaultGetPlayerInfoNodeIncRef();
if (fldr && info) if (fldr && info)
if (!fldr->IsParentOf(info->nodeId, 1)) if (!fldr->IsParentOf(info->nodeId, 1))
@ -746,7 +750,10 @@ void plNetLinkingMgr::IPostProcessLink( void )
bool plNetLinkingMgr::IPreProcessLink( void ) bool plNetLinkingMgr::IPreProcessLink( void )
{ {
plNetClientMgr * nc = plNetClientMgr::GetInstance(); // Grab some stuff we're gonna use extensively
plNetClientMgr* nc = plNetClientMgr::GetInstance();
plAgeLinkStruct* link = GetAgeLink();
plAgeInfoStruct* info = link->GetAgeInfo();
bool success = true; bool success = true;
@ -771,7 +778,7 @@ bool plNetLinkingMgr::IPreProcessLink( void )
VaultPlayerInfoNode accInfo(rvnInfo); VaultPlayerInfoNode accInfo(rvnInfo);
wchar ageInstName[MAX_PATH]; wchar ageInstName[MAX_PATH];
Uuid ageInstGuid = *GetAgeLink()->GetAgeInfo()->GetAgeInstanceGuid(); Uuid ageInstGuid = *GetAgeLink()->GetAgeInfo()->GetAgeInstanceGuid();
StrToUnicode(ageInstName, GetAgeLink()->GetAgeInfo()->GetAgeInstanceName(), arrsize(ageInstName)); StrToUnicode(ageInstName, info->GetAgeInstanceName(), arrsize(ageInstName));
accInfo.SetAgeInstName(ageInstName); accInfo.SetAgeInstName(ageInstName);
accInfo.SetAgeInstUuid(ageInstGuid); accInfo.SetAgeInstUuid(ageInstGuid);
accInfo.SetOnline(true); accInfo.SetOnline(true);
@ -783,48 +790,42 @@ bool plNetLinkingMgr::IPreProcessLink( void )
// Fixup empty fields // Fixup empty fields
if ( GetAgeLink()->GetAgeInfo()->HasAgeFilename() ) if ( GetAgeLink()->GetAgeInfo()->HasAgeFilename() )
{ {
GetAgeLink()->GetAgeInfo()->SetAgeFilename( plNetLinkingMgr::GetProperAgeName( GetAgeLink()->GetAgeInfo()->GetAgeFilename() ).c_str() ); GetAgeLink()->GetAgeInfo()->SetAgeFilename(plNetLinkingMgr::GetProperAgeName(info->GetAgeFilename()).c_str());
if ( !GetAgeLink()->GetAgeInfo()->HasAgeInstanceName() ) if (!info->HasAgeInstanceName())
{ {
GetAgeLink()->GetAgeInfo()->SetAgeInstanceName( GetAgeLink()->GetAgeInfo()->GetAgeFilename() ); info->SetAgeInstanceName(info->GetAgeFilename());
} }
} }
hsLogEntry( nc->DebugMsg( "plNetLinkingMgr: Pre-Process: Linking with %s rules...", hsLogEntry( nc->DebugMsg( "plNetLinkingMgr: Pre-Process: Linking with %s rules...",
plNetCommon::LinkingRules::LinkingRuleStr( GetAgeLink()->GetLinkingRules() ) ) ); plNetCommon::LinkingRules::LinkingRuleStr(link->GetLinkingRules())));
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// SPECIAL CASE: StartUp: force basic link // SPECIAL CASE: StartUp: force basic link
if ( stricmp( GetAgeLink()->GetAgeInfo()->GetAgeFilename(), kStartUpAgeFilename )==0 ) if (stricmp(info->GetAgeFilename(), kStartUpAgeFilename) == 0)
{ link->SetLinkingRules( plNetCommon::LinkingRules::kBasicLink );
GetAgeLink()->SetLinkingRules( plNetCommon::LinkingRules::kBasicLink );
}
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// SPECIAL CASE: Nexus: force original link // SPECIAL CASE: Nexus: force original link
if ( stricmp( GetAgeLink()->GetAgeInfo()->GetAgeFilename(), kNexusAgeFilename )==0 ) if (stricmp(info->GetAgeFilename(), kNexusAgeFilename) == 0 )
{
GetAgeLink()->SetLinkingRules( plNetCommon::LinkingRules::kOriginalBook ); GetAgeLink()->SetLinkingRules( plNetCommon::LinkingRules::kOriginalBook );
}
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// SPECIAL CASE: ACA: force original link // SPECIAL CASE: ACA: force original link
if ( stricmp( GetAgeLink()->GetAgeInfo()->GetAgeFilename(), kAvCustomizationFilename )==0 ) if (stricmp(info->GetAgeFilename(), kAvCustomizationFilename ) == 0)
{
GetAgeLink()->SetLinkingRules( plNetCommon::LinkingRules::kOriginalBook ); GetAgeLink()->SetLinkingRules( plNetCommon::LinkingRules::kOriginalBook );
}
hsLogEntry( nc->DebugMsg( "plNetLinkingMgr: Process: Linking with %s rules...", hsLogEntry( nc->DebugMsg( "plNetLinkingMgr: Process: Linking with %s rules...",
plNetCommon::LinkingRules::LinkingRuleStr( GetAgeLink()->GetLinkingRules() ) ) ); plNetCommon::LinkingRules::LinkingRuleStr(link->GetLinkingRules())));
switch ( GetAgeLink()->GetLinkingRules() ) switch (link->GetLinkingRules())
{ {
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// BASIC LINK. Link to a unique instance of the age, if no instance specified. // BASIC LINK. Link to a unique instance of the age, if no instance specified.
case plNetCommon::LinkingRules::kBasicLink: case plNetCommon::LinkingRules::kBasicLink:
if (!GetAgeLink()->GetAgeInfo()->HasAgeInstanceGuid()) if (!info->HasAgeInstanceGuid())
GetAgeLink()->GetAgeInfo()->SetAgeInstanceGuid(&plUUID(GuidGenerate())); info->SetAgeInstanceGuid(&plUUID(GuidGenerate()));
break; break;
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -835,80 +836,82 @@ bool plNetLinkingMgr::IPreProcessLink( void )
// we just want to find out if we own *any* link to the age, not the specific // we just want to find out if we own *any* link to the age, not the specific
// link that we're linking through // link that we're linking through
plAgeInfoStruct ageInfo; plAgeInfoStruct ageInfo;
ageInfo.SetAgeFilename(GetAgeLink()->GetAgeInfo()->GetAgeFilename()); ageInfo.SetAgeFilename(info->GetAgeFilename());
plAgeLinkStruct ownedLink; plAgeLinkStruct ownedLink;
if (!VaultGetOwnedAgeLink(&ageInfo, &ownedLink)) { if (!VaultGetOwnedAgeLink(&ageInfo, &ownedLink)) {
// Fill in fields for new age create. // Fill in fields for new age create.
if ( !GetAgeLink()->GetAgeInfo()->HasAgeUserDefinedName() ) if (!info->HasAgeUserDefinedName())
{ {
// set user-defined name // set user-defined name
std::string title; std::string title;
unsigned nameLen = StrLen(nc->GetPlayerName()); unsigned nameLen = StrLen(nc->GetPlayerName());
if (nc->GetPlayerName()[nameLen - 1] == 's' || nc->GetPlayerName()[nameLen - 1] == 'S') if (nc->GetPlayerName()[nameLen - 1] == 's' || nc->GetPlayerName()[nameLen - 1] == 'S')
xtl::format( title, "%s'", nc->GetPlayerName() ); xtl::format(title, "%s'", nc->GetPlayerName());
else else
xtl::format( title, "%s's", nc->GetPlayerName() ); xtl::format(title, "%s's", nc->GetPlayerName());
GetAgeLink()->GetAgeInfo()->SetAgeUserDefinedName( title.c_str() ); info->SetAgeUserDefinedName(title.c_str());
} }
if ( !GetAgeLink()->GetAgeInfo()->HasAgeDescription() ) if (!info->HasAgeDescription())
{ {
// set description // set description
std::string desc; std::string desc;
unsigned nameLen = StrLen(nc->GetPlayerName()); unsigned nameLen = StrLen(nc->GetPlayerName());
if (nc->GetPlayerName()[nameLen - 1] == 's' || nc->GetPlayerName()[nameLen - 1] == 'S') if (nc->GetPlayerName()[nameLen - 1] == 's' || nc->GetPlayerName()[nameLen - 1] == 'S')
xtl::format( desc, "%s' %s", nc->GetPlayerName(), GetAgeLink()->GetAgeInfo()->GetAgeInstanceName() ); xtl::format(desc, "%s' %s", nc->GetPlayerName(), info->GetAgeInstanceName());
else else
xtl::format( desc, "%s's %s", nc->GetPlayerName(), GetAgeLink()->GetAgeInfo()->GetAgeInstanceName() ); xtl::format(desc, "%s's %s", nc->GetPlayerName(), info->GetAgeInstanceName());
GetAgeLink()->GetAgeInfo()->SetAgeDescription( desc.c_str() ); info->SetAgeDescription(desc.c_str());
} }
if (!GetAgeLink()->GetAgeInfo()->HasAgeInstanceGuid()) { if (!info->HasAgeInstanceGuid()) {
GetAgeLink()->GetAgeInfo()->SetAgeInstanceGuid(&plUUID(GuidGenerate())); info->SetAgeInstanceGuid(&plUUID(GuidGenerate()));
} }
// register this as an owned age now before we link to it. // register this as an owned age now before we link to it.
VaultRegisterOwnedAgeAndWait(GetAgeLink()); VaultRegisterOwnedAgeAndWait(link);
} }
else if (RelVaultNode * linkNode = VaultGetOwnedAgeLinkIncRef(&ageInfo)) { else if (RelVaultNode* linkNode = VaultGetOwnedAgeLinkIncRef(&ageInfo)) {
// We have the age in our AgesIOwnFolder. If its volatile, dump it for the new one. // We have the age in our AgesIOwnFolder. If its volatile, dump it for the new one.
VaultAgeLinkNode linkAcc(linkNode); VaultAgeLinkNode linkAcc(linkNode);
if (linkAcc.volat) { if (linkAcc.volat) {
if (VaultUnregisterOwnedAgeAndWait(&ageInfo)) { if (VaultUnregisterOwnedAgeAndWait(&ageInfo)) {
// Fill in fields for new age create. // Fill in fields for new age create.
if ( !GetAgeLink()->GetAgeInfo()->HasAgeUserDefinedName() ) if (!info->HasAgeUserDefinedName() )
{ {
// set user-defined name // set user-defined name
std::string title; std::string title;
unsigned nameLen = StrLen(nc->GetPlayerName()); unsigned nameLen = StrLen(nc->GetPlayerName());
if (nc->GetPlayerName()[nameLen - 1] == 's' || nc->GetPlayerName()[nameLen - 1] == 'S') if (nc->GetPlayerName()[nameLen - 1] == 's' || nc->GetPlayerName()[nameLen - 1] == 'S')
xtl::format( title, "%s'", nc->GetPlayerName() ); xtl::format(title, "%s'", nc->GetPlayerName());
else else
xtl::format( title, "%s's", nc->GetPlayerName() ); xtl::format(title, "%s's", nc->GetPlayerName());
GetAgeLink()->GetAgeInfo()->SetAgeUserDefinedName( title.c_str() ); info->SetAgeUserDefinedName(title.c_str());
} }
if ( !GetAgeLink()->GetAgeInfo()->HasAgeDescription() )
if (!info->HasAgeDescription())
{ {
// set description // set description
std::string desc; std::string desc;
unsigned nameLen = StrLen(nc->GetPlayerName()); unsigned nameLen = StrLen(nc->GetPlayerName());
if (nc->GetPlayerName()[nameLen - 1] == 's' || nc->GetPlayerName()[nameLen - 1] == 'S') if (nc->GetPlayerName()[nameLen - 1] == 's' || nc->GetPlayerName()[nameLen - 1] == 'S')
xtl::format( desc, "%s' %s", nc->GetPlayerName(), GetAgeLink()->GetAgeInfo()->GetAgeInstanceName() ); xtl::format(desc, "%s' %s", nc->GetPlayerName(), info->GetAgeInstanceName());
else else
xtl::format( desc, "%s's %s", nc->GetPlayerName(), GetAgeLink()->GetAgeInfo()->GetAgeInstanceName() ); xtl::format(desc, "%s's %s", nc->GetPlayerName(), info->GetAgeInstanceName());
GetAgeLink()->GetAgeInfo()->SetAgeDescription( desc.c_str() ); info->SetAgeDescription( desc.c_str() );
} }
if (!GetAgeLink()->GetAgeInfo()->HasAgeInstanceGuid()) {
GetAgeLink()->GetAgeInfo()->SetAgeInstanceGuid(&plUUID(GuidGenerate())); if (!info->HasAgeInstanceGuid()) {
info->SetAgeInstanceGuid(&plUUID(GuidGenerate()));
} }
VaultRegisterOwnedAgeAndWait(GetAgeLink()); VaultRegisterOwnedAgeAndWait(link);
} }
} }
else { else {
if (stricmp(GetAgeLink()->GetAgeInfo()->GetAgeFilename(), kNeighborhoodAgeFilename) == 0) { if (stricmp(info->GetAgeFilename(), kNeighborhoodAgeFilename) == 0) {
// if we get here then its because we're linking to a neighborhood that we don't belong to // if we get here then it's because we're linking to a neighborhood that we don't belong to
// and our own neighborhood book is not volatile, so really we want to basic link // and our own neighborhood book is not volatile, so really we want to basic link
GetAgeLink()->SetLinkingRules(plNetCommon::LinkingRules::kBasicLink); link->SetLinkingRules(plNetCommon::LinkingRules::kBasicLink);
success = true; success = true;
break; break;
@ -917,7 +920,8 @@ bool plNetLinkingMgr::IPreProcessLink( void )
linkNode->DecRef(); linkNode->DecRef();
} }
} }
GetAgeLink()->SetLinkingRules( plNetCommon::LinkingRules::kOwnedBook );
link->SetLinkingRules( plNetCommon::LinkingRules::kOwnedBook );
// falls thru to OWNED BOOK case... // falls thru to OWNED BOOK case...
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -925,11 +929,11 @@ bool plNetLinkingMgr::IPreProcessLink( void )
case plNetCommon::LinkingRules::kOwnedBook: case plNetCommon::LinkingRules::kOwnedBook:
{ {
plAgeLinkStruct ownedLink; plAgeLinkStruct ownedLink;
if (VaultGetOwnedAgeLink(GetAgeLink()->GetAgeInfo(), &ownedLink)) { if (VaultGetOwnedAgeLink(info, &ownedLink)) {
GetAgeLink()->GetAgeInfo()->CopyFrom(ownedLink.GetAgeInfo()); GetAgeLink()->GetAgeInfo()->CopyFrom(ownedLink.GetAgeInfo());
// Remember spawn point (treasure book support) // Remember spawn point (treasure book support)
plSpawnPointInfo theSpawnPt = GetAgeLink()->SpawnPoint(); plSpawnPointInfo theSpawnPt = link->SpawnPoint();
VaultAddOwnedAgeSpawnPoint(*GetAgeLink()->GetAgeInfo()->GetAgeInstanceGuid(), theSpawnPt); VaultAddOwnedAgeSpawnPoint(*info->GetAgeInstanceGuid(), theSpawnPt);
} }
else { else {
success = false; success = false;
@ -942,8 +946,8 @@ bool plNetLinkingMgr::IPreProcessLink( void )
case plNetCommon::LinkingRules::kVisitBook: case plNetCommon::LinkingRules::kVisitBook:
{ {
plAgeLinkStruct visitLink; plAgeLinkStruct visitLink;
if (VaultGetVisitAgeLink(GetAgeLink()->GetAgeInfo(), &visitLink)) if (VaultGetVisitAgeLink(info, &visitLink))
GetAgeLink()->GetAgeInfo()->CopyFrom(visitLink.GetAgeInfo()); info->CopyFrom(visitLink.GetAgeInfo());
else else
success = false; success = false;
} }
@ -955,8 +959,8 @@ bool plNetLinkingMgr::IPreProcessLink( void )
case plNetCommon::LinkingRules::kSubAgeBook: case plNetCommon::LinkingRules::kSubAgeBook:
{ {
plAgeLinkStruct subAgeLink; plAgeLinkStruct subAgeLink;
if (VaultAgeFindOrCreateSubAgeLinkAndWait(GetAgeLink()->GetAgeInfo(), &subAgeLink, NetCommGetAge()->ageInstId)) if (VaultAgeFindOrCreateSubAgeLinkAndWait(info, &subAgeLink, NetCommGetAge()->ageInstId))
GetAgeLink()->GetAgeInfo()->CopyFrom(subAgeLink.GetAgeInfo()); info->CopyFrom(subAgeLink.GetAgeInfo());
else else
success = false; success = false;
} }
@ -969,28 +973,28 @@ bool plNetLinkingMgr::IPreProcessLink( void )
{ {
plAgeLinkStruct childLink; plAgeLinkStruct childLink;
wchar parentAgeName[MAX_PATH]; wchar parentAgeName[MAX_PATH];
if (GetAgeLink()->HasParentAgeFilename()) { if (link->HasParentAgeFilename()) {
StrToUnicode(parentAgeName, GetAgeLink()->GetParentAgeFilename(), arrsize(parentAgeName)); StrToUnicode(parentAgeName, link->GetParentAgeFilename(), arrsize(parentAgeName));
success = VaultAgeFindOrCreateChildAgeLinkAndWait(parentAgeName, GetAgeLink()->GetAgeInfo(), &childLink); success = VaultAgeFindOrCreateChildAgeLinkAndWait(parentAgeName, info, &childLink);
} }
else { else {
success = VaultAgeFindOrCreateChildAgeLinkAndWait(nil, GetAgeLink()->GetAgeInfo(), &childLink); success = VaultAgeFindOrCreateChildAgeLinkAndWait(nil, info, &childLink);
} }
if (success) if (success)
GetAgeLink()->GetAgeInfo()->CopyFrom(childLink.GetAgeInfo()); info->CopyFrom(childLink.GetAgeInfo());
} }
break; break;
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// ??? // ???
DEFAULT_FATAL(GetAgeLink()->GetLinkingRules()); DEFAULT_FATAL(link->GetLinkingRules());
} }
hsLogEntry( nc->DebugMsg( "plNetLinkingMgr: Post-Process: Linking with %s rules...", hsLogEntry( nc->DebugMsg( "plNetLinkingMgr: Post-Process: Linking with %s rules...",
plNetCommon::LinkingRules::LinkingRuleStr( GetAgeLink()->GetLinkingRules() ) ) ); plNetCommon::LinkingRules::LinkingRuleStr(link->GetLinkingRules())));
hsAssert( GetAgeLink()->GetAgeInfo()->HasAgeFilename(), "AgeLink has no AgeFilename. Link will fail." ); hsAssert(info->HasAgeFilename(), "AgeLink has no AgeFilename. Link will fail.");
return success; return success;
} }

Loading…
Cancel
Save