Compilation...
git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@31 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
@@ -32,7 +32,7 @@ import com.threerings.parlor.util.ParlorContext;
|
|||||||
* outstanding invitations generated by or targeted to this client.
|
* outstanding invitations generated by or targeted to this client.
|
||||||
*/
|
*/
|
||||||
public class Invitation
|
public class Invitation
|
||||||
implements ParlorCodes, ParlorService_InviteListener
|
implements ParlorService_InviteListener
|
||||||
{
|
{
|
||||||
/** The unique id for this invitation (as assigned by the
|
/** The unique id for this invitation (as assigned by the
|
||||||
* server). This is -1 until we receive an acknowledgement from
|
* server). This is -1 until we receive an acknowledgement from
|
||||||
@@ -65,7 +65,7 @@ public class Invitation
|
|||||||
{
|
{
|
||||||
// generate the invocation service request
|
// generate the invocation service request
|
||||||
_pservice.respond(_ctx.getClient(), inviteId,
|
_pservice.respond(_ctx.getClient(), inviteId,
|
||||||
INVITATION_ACCEPTED, null, this);
|
ParlorCodes.INVITATION_ACCEPTED, null, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,7 +79,7 @@ public class Invitation
|
|||||||
{
|
{
|
||||||
// generate the invocation service request
|
// generate the invocation service request
|
||||||
_pservice.respond(_ctx.getClient(), inviteId,
|
_pservice.respond(_ctx.getClient(), inviteId,
|
||||||
INVITATION_REFUSED, message, this);
|
ParlorCodes.INVITATION_REFUSED, message, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,7 +118,7 @@ public class Invitation
|
|||||||
|
|
||||||
// generate the invocation service request
|
// generate the invocation service request
|
||||||
_pservice.respond(_ctx.getClient(), inviteId,
|
_pservice.respond(_ctx.getClient(), inviteId,
|
||||||
INVITATION_COUNTERED, config, this);
|
ParlorCodes.INVITATION_COUNTERED, config, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
@@ -148,7 +148,7 @@ public class Invitation
|
|||||||
* Called by the parlor director when we receive a response to an
|
* Called by the parlor director when we receive a response to an
|
||||||
* invitation initiated by this client.
|
* invitation initiated by this client.
|
||||||
*/
|
*/
|
||||||
protected function receivedResponse (code :int, arg :Object) :void
|
internal function receivedResponse (code :int, arg :Object) :void
|
||||||
{
|
{
|
||||||
// make sure we have an observer to notify
|
// make sure we have an observer to notify
|
||||||
if (_observer == null) {
|
if (_observer == null) {
|
||||||
@@ -160,20 +160,20 @@ public class Invitation
|
|||||||
// notify the observer
|
// notify the observer
|
||||||
try {
|
try {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case INVITATION_ACCEPTED:
|
case ParlorCodes.INVITATION_ACCEPTED:
|
||||||
_observer.invitationAccepted(this);
|
_observer.invitationAccepted(this);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INVITATION_REFUSED:
|
case ParlorCodes.INVITATION_REFUSED:
|
||||||
_observer.invitationRefused(this, (arg as String));
|
_observer.invitationRefused(this, (arg as String));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INVITATION_COUNTERED:
|
case ParlorCodes.INVITATION_COUNTERED:
|
||||||
_observer.invitationCountered(this, (arg as GameConfig));
|
_observer.invitationCountered(this, (arg as GameConfig));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (err :Error) {
|
} catch (e :Error) {
|
||||||
var log :Log = Log.getLog(this);
|
var log :Log = Log.getLog(this);
|
||||||
log.warning("Invitation response observer choked on response " +
|
log.warning("Invitation response observer choked on response " +
|
||||||
"[code=" + code + ", arg=" + arg +
|
"[code=" + code + ", arg=" + arg +
|
||||||
@@ -183,7 +183,7 @@ public class Invitation
|
|||||||
|
|
||||||
// unless the invitation was countered, we can remove it from the
|
// unless the invitation was countered, we can remove it from the
|
||||||
// pending table because it's resolved
|
// pending table because it's resolved
|
||||||
if (code != INVITATION_COUNTERED) {
|
if (code != ParlorCodes.INVITATION_COUNTERED) {
|
||||||
_ctx.getParlorDirector().clearInvitation(this);
|
_ctx.getParlorDirector().clearInvitation(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.threerings.parlor.client.ParlorReceiver;
|
|||||||
import com.threerings.parlor.game.data.GameConfig;
|
import com.threerings.parlor.game.data.GameConfig;
|
||||||
import com.threerings.presents.client.InvocationDecoder;
|
import com.threerings.presents.client.InvocationDecoder;
|
||||||
import com.threerings.util.Name;
|
import com.threerings.util.Name;
|
||||||
|
import com.threerings.util.Integer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatches calls to a {@link ParlorReceiver} instance.
|
* Dispatches calls to a {@link ParlorReceiver} instance.
|
||||||
|
|||||||
@@ -27,9 +27,10 @@ import com.threerings.util.Name;
|
|||||||
|
|
||||||
import com.threerings.presents.client.BasicDirector;
|
import com.threerings.presents.client.BasicDirector;
|
||||||
import com.threerings.presents.client.Client;
|
import com.threerings.presents.client.Client;
|
||||||
|
import com.threerings.presents.client.ClientEvent;
|
||||||
import com.threerings.presents.client.InvocationService;
|
import com.threerings.presents.client.InvocationService;
|
||||||
|
import com.threerings.presents.client.InvocationService_ConfirmListener;
|
||||||
|
|
||||||
import com.threerings.parlor.Log;
|
|
||||||
import com.threerings.parlor.data.ParlorCodes;
|
import com.threerings.parlor.data.ParlorCodes;
|
||||||
import com.threerings.parlor.game.data.GameConfig;
|
import com.threerings.parlor.game.data.GameConfig;
|
||||||
import com.threerings.parlor.util.ParlorContext;
|
import com.threerings.parlor.util.ParlorContext;
|
||||||
@@ -42,7 +43,7 @@ import com.threerings.parlor.util.ParlorContext;
|
|||||||
* that started.
|
* that started.
|
||||||
*/
|
*/
|
||||||
public class ParlorDirector extends BasicDirector
|
public class ParlorDirector extends BasicDirector
|
||||||
implements ParlorCodes, ParlorReceiver
|
implements ParlorReceiver
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Constructs a parlor director and provides it with the parlor
|
* Constructs a parlor director and provides it with the parlor
|
||||||
@@ -113,9 +114,9 @@ public class ParlorDirector extends BasicDirector
|
|||||||
{
|
{
|
||||||
// create the invitation record
|
// create the invitation record
|
||||||
var invite :Invitation = new Invitation(
|
var invite :Invitation = new Invitation(
|
||||||
_ctx, _pservice, invitee, config, observer);
|
_pctx, _pservice, invitee, config, observer);
|
||||||
// submit the invitation request to the server
|
// submit the invitation request to the server
|
||||||
_pservice.invite(_ctx.getClient(), invitee, config, invite);
|
_pservice.invite(_pctx.getClient(), invitee, config, invite);
|
||||||
// and return the invitation to the caller
|
// and return the invitation to the caller
|
||||||
return invite;
|
return invite;
|
||||||
}
|
}
|
||||||
@@ -129,13 +130,13 @@ public class ParlorDirector extends BasicDirector
|
|||||||
* cannot be started.
|
* cannot be started.
|
||||||
*/
|
*/
|
||||||
public function startSolitaire (
|
public function startSolitaire (
|
||||||
config :GameConfig, listener :InvocationService.ConfirmListener) :void
|
config :GameConfig, listener :InvocationService_ConfirmListener) :void
|
||||||
{
|
{
|
||||||
_pservice.startSolitaire(_ctx.getClient(), config, listener);
|
_pservice.startSolitaire(_pctx.getClient(), config, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
public function clientDidLogoff (event :ClientEvent) :void
|
override public function clientDidLogoff (event :ClientEvent) :void
|
||||||
{
|
{
|
||||||
super.clientDidLogoff(event);
|
super.clientDidLogoff(event);
|
||||||
_pservice = null;
|
_pservice = null;
|
||||||
@@ -143,10 +144,11 @@ public class ParlorDirector extends BasicDirector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
protected function fetchServices (client :Client) :void
|
override protected function fetchServices (client :Client) :void
|
||||||
{
|
{
|
||||||
// get a handle on our parlor services
|
// get a handle on our parlor services
|
||||||
_pservice = (client.requireService(ParlorService) as ParlorService);
|
_pservice = (client.requireService(ParlorService) as ParlorService);
|
||||||
|
super.fetchServices(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
@@ -164,7 +166,7 @@ public class ParlorDirector extends BasicDirector
|
|||||||
// if none of the observers took matters into their own hands,
|
// if none of the observers took matters into their own hands,
|
||||||
// then we'll head on over to the game room ourselves
|
// then we'll head on over to the game room ourselves
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
_ctx.getLocationDirector().moveTo(gameOid);
|
_pctx.getLocationDirector().moveTo(gameOid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,8 +175,8 @@ public class ParlorDirector extends BasicDirector
|
|||||||
remoteId :int, inviter :Name, config :GameConfig) :void
|
remoteId :int, inviter :Name, config :GameConfig) :void
|
||||||
{
|
{
|
||||||
// create an invitation record for this invitation
|
// create an invitation record for this invitation
|
||||||
invite :Invitation = new Invitation(
|
var invite :Invitation = new Invitation(
|
||||||
_ctx, _pservice, inviter, config, null);
|
_pctx, _pservice, inviter, config, null);
|
||||||
invite.inviteId = remoteId;
|
invite.inviteId = remoteId;
|
||||||
|
|
||||||
// put it in the pending invitations table
|
// put it in the pending invitations table
|
||||||
@@ -218,7 +220,7 @@ public class ParlorDirector extends BasicDirector
|
|||||||
* Register a new invitation in our pending invitations table. The
|
* Register a new invitation in our pending invitations table. The
|
||||||
* invitation will call this when it knows its invitation id.
|
* invitation will call this when it knows its invitation id.
|
||||||
*/
|
*/
|
||||||
protected function registerInvitation (invite :Invitation) :void
|
public function registerInvitation (invite :Invitation) :void
|
||||||
{
|
{
|
||||||
_pendingInvites.put(invite.inviteId, invite);
|
_pendingInvites.put(invite.inviteId, invite);
|
||||||
}
|
}
|
||||||
@@ -227,7 +229,7 @@ public class ParlorDirector extends BasicDirector
|
|||||||
* Called by an invitation when it knows it is no longer and can be
|
* Called by an invitation when it knows it is no longer and can be
|
||||||
* cleared from the pending invitations table.
|
* cleared from the pending invitations table.
|
||||||
*/
|
*/
|
||||||
protected function clearInvitation (invite :Invitation) :void
|
public function clearInvitation (invite :Invitation) :void
|
||||||
{
|
{
|
||||||
_pendingInvites.remove(invite.inviteId);
|
_pendingInvites.remove(invite.inviteId);
|
||||||
}
|
}
|
||||||
@@ -250,3 +252,4 @@ public class ParlorDirector extends BasicDirector
|
|||||||
* notification. */
|
* notification. */
|
||||||
protected var _grobs :Array = new Array();
|
protected var _grobs :Array = new Array();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ public interface ParlorReceiver extends InvocationReceiver
|
|||||||
* @param config the configuration information for the game to which
|
* @param config the configuration information for the game to which
|
||||||
* we've been invited.
|
* we've been invited.
|
||||||
*/
|
*/
|
||||||
function receivedInvite (remoteId :int, inviter :Name, config :GameConfig);
|
function receivedInvite (
|
||||||
|
remoteId :int, inviter :Name, config :GameConfig) :void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the invocation services when another user has responded
|
* Called by the invocation services when another user has responded
|
||||||
@@ -72,7 +73,8 @@ public interface ParlorReceiver extends InvocationReceiver
|
|||||||
* provided). In the case of a countered invitation, a new game config
|
* provided). In the case of a countered invitation, a new game config
|
||||||
* object with the modified game configuration.
|
* object with the modified game configuration.
|
||||||
*/
|
*/
|
||||||
function receivedInviteResponse (remoteId :int, code :int, arg :Object);
|
function receivedInviteResponse (
|
||||||
|
remoteId :int, code :int, arg :Object) :void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the invocation services when an outstanding invitation
|
* Called by the invocation services when an outstanding invitation
|
||||||
@@ -80,6 +82,6 @@ public interface ParlorReceiver extends InvocationReceiver
|
|||||||
*
|
*
|
||||||
* @param remoteId the indentifier of the cancelled invitation.
|
* @param remoteId the indentifier of the cancelled invitation.
|
||||||
*/
|
*/
|
||||||
function receivedInviteCancellation (remoteId :int);
|
function receivedInviteCancellation (remoteId :int) :void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import com.threerings.util.Name;
|
|||||||
|
|
||||||
import com.threerings.presents.client.Client;
|
import com.threerings.presents.client.Client;
|
||||||
import com.threerings.presents.client.InvocationService;
|
import com.threerings.presents.client.InvocationService;
|
||||||
|
import com.threerings.presents.client.InvocationService_InvocationListener;
|
||||||
|
import com.threerings.presents.client.InvocationService_ConfirmListener;
|
||||||
|
|
||||||
import com.threerings.parlor.data.TableConfig;
|
import com.threerings.parlor.data.TableConfig;
|
||||||
|
|
||||||
@@ -54,7 +56,7 @@ public interface ParlorService extends InvocationService
|
|||||||
*/
|
*/
|
||||||
function invite (
|
function invite (
|
||||||
client :Client, invitee :Name, config :GameConfig,
|
client :Client, invitee :Name, config :GameConfig,
|
||||||
listener :InviteListener) :void;
|
listener :ParlorService_InviteListener) :void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You probably don't want to call this directly, but want to call one
|
* You probably don't want to call this directly, but want to call one
|
||||||
@@ -76,7 +78,7 @@ public interface ParlorService extends InvocationService
|
|||||||
*/
|
*/
|
||||||
function respond (
|
function respond (
|
||||||
client :Client, inviteId :int, code :int, arg :Object,
|
client :Client, inviteId :int, code :int, arg :Object,
|
||||||
listener :InvocationListener) :void;
|
listener :InvocationService_InvocationListener) :void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You probably don't want to call this directly, but want to call
|
* You probably don't want to call this directly, but want to call
|
||||||
@@ -89,7 +91,8 @@ public interface ParlorService extends InvocationService
|
|||||||
* @param listener will receive and process the response.
|
* @param listener will receive and process the response.
|
||||||
*/
|
*/
|
||||||
function cancel (
|
function cancel (
|
||||||
client :Client, inviteId :int, listener :InvocationListener) :void;
|
client :Client, inviteId :int,
|
||||||
|
listener :InvocationService_InvocationListener) :void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You probably don't want to call this directly, but want to call
|
* You probably don't want to call this directly, but want to call
|
||||||
@@ -106,7 +109,7 @@ public interface ParlorService extends InvocationService
|
|||||||
*/
|
*/
|
||||||
function createTable (
|
function createTable (
|
||||||
client :Client, lobbyOid :int, tableConfig :TableConfig,
|
client :Client, lobbyOid :int, tableConfig :TableConfig,
|
||||||
config :GameConfig, listener :TableListener) :void;
|
config :GameConfig, listener :ParlorService_TableListener) :void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You probably don't want to call this directly, but want to call
|
* You probably don't want to call this directly, but want to call
|
||||||
@@ -122,8 +125,8 @@ public interface ParlorService extends InvocationService
|
|||||||
* @param listener will receive and process the response.
|
* @param listener will receive and process the response.
|
||||||
*/
|
*/
|
||||||
function joinTable (
|
function joinTable (
|
||||||
client :Client, lobbyOid :int, tableId :int,
|
client :Client, lobbyOid :int, tableId :int, position :int,
|
||||||
position :int, listener :InvocationListener) :void;
|
listener :InvocationService_InvocationListener) :void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You probably don't want to call this directly, but want to call
|
* You probably don't want to call this directly, but want to call
|
||||||
@@ -138,7 +141,7 @@ public interface ParlorService extends InvocationService
|
|||||||
*/
|
*/
|
||||||
function leaveTable (
|
function leaveTable (
|
||||||
client :Client, lobbyOid :int, tableId :int,
|
client :Client, lobbyOid :int, tableId :int,
|
||||||
listener :InvocationListener) :void;
|
listener :InvocationService_InvocationListener) :void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests to start a single player game with the specified game
|
* Requests to start a single player game with the specified game
|
||||||
@@ -146,6 +149,6 @@ public interface ParlorService extends InvocationService
|
|||||||
*/
|
*/
|
||||||
function startSolitaire (
|
function startSolitaire (
|
||||||
client :Client, config :GameConfig,
|
client :Client, config :GameConfig,
|
||||||
listener :ConfirmListener) :void;
|
listener :InvocationService_ConfirmListener) :void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package com.threerings.parlor.client {
|
package com.threerings.parlor.client {
|
||||||
|
|
||||||
import com.threerings.presents.client.InvocationListener;
|
import com.threerings.presents.client.InvocationService_InvocationListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to communicate responses to {@link #invite} requests.
|
* Used to communicate responses to {@link #invite} requests.
|
||||||
*/
|
*/
|
||||||
public interface ParlorService_InviteListener extends InvocationListener
|
public interface ParlorService_InviteListener
|
||||||
|
extends InvocationService_InvocationListener
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Called in response to a successful {@link #invite} request.
|
* Called in response to a successful {@link #invite} request.
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package com.threerings.parlor.client {
|
package com.threerings.parlor.client {
|
||||||
|
|
||||||
import com.threerings.presents.client.InvocationListener;
|
import com.threerings.presents.client.InvocationService_InvocationListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to communicate responses to {@link #createTable}, {@link
|
* Used to communicate responses to {@link #createTable}, {@link
|
||||||
* #joinTable}, and {@link #leaveTable} requests.
|
* #joinTable}, and {@link #leaveTable} requests.
|
||||||
*/
|
*/
|
||||||
public interface ParlorService_TableListener extends InvocationListener
|
public interface ParlorService_TableListener
|
||||||
|
extends InvocationService_InvocationListener
|
||||||
{
|
{
|
||||||
function tableCreated (tableId :int) :void;
|
function tableCreated (tableId :int) :void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public /*abstract*/ class TableConfigurator
|
|||||||
*/
|
*/
|
||||||
public /*abstract*/ function isEmpty () :Boolean
|
public /*abstract*/ function isEmpty () :Boolean
|
||||||
{
|
{
|
||||||
return true;
|
throw new Error("abstract");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.threerings.util.ClassUtil;
|
|||||||
import com.threerings.util.Cloneable;
|
import com.threerings.util.Cloneable;
|
||||||
import com.threerings.util.Hashable;
|
import com.threerings.util.Hashable;
|
||||||
import com.threerings.util.Name;
|
import com.threerings.util.Name;
|
||||||
|
import com.threerings.util.StringUtil;
|
||||||
|
|
||||||
import com.threerings.io.TypedArray;
|
import com.threerings.io.TypedArray;
|
||||||
|
|
||||||
@@ -70,9 +71,9 @@ public /*abstract*/ class GameConfig extends PlaceConfig
|
|||||||
* used to translate the translatable strings used to describe the
|
* used to translate the translatable strings used to describe the
|
||||||
* game config parameters.
|
* game config parameters.
|
||||||
*/
|
*/
|
||||||
public function getBundleName () :String
|
public /*abstract*/ function getBundleName () :String
|
||||||
{
|
{
|
||||||
Log.getLog(this).warning("this method is actually abstract.");
|
throw new Error("abstract");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,7 +81,10 @@ public /*abstract*/ class GameConfig extends PlaceConfig
|
|||||||
* for configuring this instance prior to starting the game. If no
|
* for configuring this instance prior to starting the game. If no
|
||||||
* configuration is necessary, this method should return null.
|
* configuration is necessary, this method should return null.
|
||||||
*/
|
*/
|
||||||
public function createConfigurator () :GameConfigurator
|
public /*abstract*/ function createConfigurator () :GameConfigurator
|
||||||
|
{
|
||||||
|
throw new Error("abstract");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a table configurator for initializing 'table' properties
|
* Creates a table configurator for initializing 'table' properties
|
||||||
@@ -151,7 +155,7 @@ public /*abstract*/ class GameConfig extends PlaceConfig
|
|||||||
// from Cloneable
|
// from Cloneable
|
||||||
public function clone () :Object
|
public function clone () :Object
|
||||||
{
|
{
|
||||||
var copy :GameConfig = ClassUtil.newInstance(this);
|
var copy :GameConfig = (ClassUtil.newInstance(this) as GameConfig);
|
||||||
copy.players = this.players;
|
copy.players = this.players;
|
||||||
copy.rated = this.rated;
|
copy.rated = this.rated;
|
||||||
copy.ais = this.ais;
|
copy.ais = this.ais;
|
||||||
|
|||||||
@@ -381,7 +381,10 @@ public class SpotSceneDirector extends BasicDirector
|
|||||||
clearCluster(true);
|
clearCluster(true);
|
||||||
|
|
||||||
// stop listening to the client object
|
// stop listening to the client object
|
||||||
event.getClient().getClientObject().removeListener(this);
|
var clientObj :ClientObject = event.getClient().getClientObject();
|
||||||
|
if (clientObj != null) {
|
||||||
|
clientObj.removeListener(this);
|
||||||
|
}
|
||||||
_self = null;
|
_self = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user