Create group chat session on send, if it doesn't exist

This commit is contained in:
Casper Warden
2017-12-15 19:13:45 +00:00
parent 03c251d59d
commit 00a32523b9
29 changed files with 336 additions and 81 deletions

View File

@@ -36,6 +36,7 @@ export class Agent
regionAccess: string;
agentAccess: string;
currentRegion: Region;
chatSessions: string[] = [];
controlFlags: ControlFlags = 0;
openID: {
'token'?: string,
@@ -80,6 +81,25 @@ export class Agent
this.clientEvents = clientEvents;
}
addChatSession(uuid: UUID)
{
const str = uuid.toString();
if (this.chatSessions.indexOf(str) === -1)
{
this.chatSessions.push(str);
}
}
hasChatSession(uuid: UUID): boolean
{
const str = uuid.toString();
if (this.chatSessions.indexOf(str) === -1)
{
return false;
}
return true;
}
setCurrentRegion(region: Region)
{
this.currentRegion = region;

View File

@@ -7,6 +7,7 @@ import {EventQueueClient} from './EventQueueClient';
import {UUID} from './UUID';
import {HTTPAssets} from '../enums/HTTPAssets';
import {ClientEvents} from "./ClientEvents";
import {Agent} from './Agent';
export class Caps
{
@@ -15,10 +16,12 @@ export class Caps
private gotSeedCap: boolean = false;
private capabilities: { [key: string]: string } = {};
private clientEvents: ClientEvents;
private agent: Agent;
eventQueueClient: EventQueueClient | null = null;
constructor(region: Region, seedURL: string, clientEvents: ClientEvents)
constructor(agent: Agent, region: Region, seedURL: string, clientEvents: ClientEvents)
{
this.agent = agent;
this.clientEvents = clientEvents;
this.region = region;
const req: string[] = [];
@@ -122,7 +125,7 @@ export class Caps
{
this.eventQueueClient.shutdown();
}
this.eventQueueClient = new EventQueueClient(this, this.clientEvents);
this.eventQueueClient = new EventQueueClient(this.agent, this, this.clientEvents);
}
}).catch((err) =>
{

View File

@@ -7,6 +7,7 @@ import {GroupInviteEvent} from '../events/GroupInviteEvent';
import {FriendRequestEvent} from '../events/FriendRequestEvent';
import {DisconnectEvent} from '../events/DisconnectEvent';
import {GroupChatEvent} from '../events/GroupChatEvent';
import {GroupChatSessionJoinEvent} from '../events/GroupChatSessionJoinEvent';
export class ClientEvents
{
@@ -19,4 +20,5 @@ export class ClientEvents
onDisconnected: Subject<DisconnectEvent> = new Subject<DisconnectEvent>();
onCircuitLatency: Subject<number> = new Subject<number>();
onGroupChat: Subject<GroupChatEvent> = new Subject<GroupChatEvent>();
onGroupChatSessionJoin: Subject<GroupChatSessionJoinEvent> = new Subject<GroupChatSessionJoinEvent>();
}

View File

@@ -9,6 +9,8 @@ import {TeleportEventType} from '../enums/TeleportEventType';
import {GroupChatEvent} from '../events/GroupChatEvent';
import {Utils} from './Utils';
import {UUID} from './UUID';
import {Agent} from './Agent';
import {GroupChatSessionJoinEvent} from '../events/GroupChatSessionJoinEvent';
export class EventQueueClient
{
@@ -17,9 +19,11 @@ export class EventQueueClient
done = false;
currentRequest: request.Request | null = null;
private clientEvents: ClientEvents;
private agent: Agent;
constructor(caps: Caps, clientEvents: ClientEvents)
constructor(agent: Agent, caps: Caps, clientEvents: ClientEvents)
{
this.agent = agent;
this.clientEvents = clientEvents;
this.caps = caps;
this.Get();
@@ -255,6 +259,21 @@ export class EventQueueClient
this.clientEvents.onTeleportEvent.next(tpEvent);
break;
}
case "ChatterBoxSessionStartReply":
{
if (event['body'])
{
const gcsje = new GroupChatSessionJoinEvent();
gcsje.sessionID = new UUID(event['body']['session_id'].toString());
gcsje.success = event['body']['success'];
if (gcsje.success)
{
this.agent.addChatSession(gcsje.sessionID);
}
this.clientEvents.onGroupChatSessionJoin.next(gcsje);
}
break;
}
case 'ChatterBoxInvitation':
{
if (event['body'] && event['body']['instantmessage'] && event['body']['instantmessage']['message_params'] && event['body']['instantmessage']['message_params']['id'])
@@ -275,6 +294,12 @@ export class EventQueueClient
this.caps.capsRequestXML('ChatSessionRequest', requestedFolders).then((result: any) =>
{
this.agent.addChatSession(groupChatEvent.groupID);
const gcsje = new GroupChatSessionJoinEvent();
gcsje.sessionID = groupChatEvent.groupID;
gcsje.success = true;
this.clientEvents.onGroupChatSessionJoin.next(gcsje);
this.clientEvents.onGroupChat.next(groupChatEvent);
}).catch((err) =>
{

View File

@@ -18,9 +18,11 @@ export class Region
comms: Comms;
clientEvents: ClientEvents;
options: BotOptionFlags;
agent: Agent;
constructor(agent: Agent, clientEvents: ClientEvents, options: BotOptionFlags)
{
this.agent = agent;
this.options = options;
this.clientEvents = clientEvents;
this.circuit = new Circuit(clientEvents);
@@ -36,7 +38,7 @@ export class Region
}
activateCaps(seedURL: string)
{
this.caps = new Caps(this, seedURL, this.clientEvents);
this.caps = new Caps(this.agent, this, seedURL, this.clientEvents);
}
shutdown()
{

View File

@@ -36,7 +36,6 @@ export class UUID
else
{
console.error('Can\'t accept UUIDs of type ' + typeof buf);
console.trace();
}
}
}

View File

@@ -9,6 +9,8 @@ import {ChatType} from '../../enums/ChatType';
import {InstantMessageDialog} from '../../enums/InstantMessageDialog';
import Timer = NodeJS.Timer;
import {GroupInviteEvent} from '../../events/GroupInviteEvent';
import * as LLSD from 'llsd';
import {GroupChatSessionJoinEvent} from '../../events/GroupChatSessionJoinEvent';
export class CommunicationsCommands extends CommandsBase
{
@@ -305,38 +307,106 @@ export class CommunicationsCommands extends CommandsBase
});
}
startChatSession(sessionID: UUID | string): Promise<void>
{
return new Promise<void>((resolve, reject) =>
{
if (typeof sessionID === 'string')
{
sessionID = new UUID(sessionID);
}
if (this.agent.hasChatSession(sessionID))
{
resolve();
}
else
{
const circuit = this.circuit;
const agentName = this.agent.firstName + ' ' + this.agent.lastName;
const im: ImprovedInstantMessageMessage = new ImprovedInstantMessageMessage();
im.AgentData = {
AgentID: this.agent.agentID,
SessionID: circuit.sessionID
};
im.MessageBlock = {
FromGroup: false,
ToAgentID: sessionID,
ParentEstateID: 0,
RegionID: UUID.zero(),
Position: Vector3.getZero(),
Offline: 0,
Dialog: InstantMessageDialog.SessionGroupStart,
ID: sessionID,
Timestamp: Math.floor(new Date().getTime() / 1000),
FromAgentName: Utils.StringToBuffer(agentName),
Message: Utils.StringToBuffer(''),
BinaryBucket: Utils.StringToBuffer('')
};
im.EstateBlock = {
EstateID: 0
};
const waitForJoin = this.currentRegion.clientEvents.onGroupChatSessionJoin.subscribe((event: GroupChatSessionJoinEvent) =>
{
if (event.sessionID.toString() === sessionID.toString())
{
if (event.success)
{
waitForJoin.unsubscribe();
resolve();
}
else
{
reject();
}
}
});
const sequenceNo = circuit.sendMessage(im, PacketFlags.Reliable);
}
});
}
sendGroupMessage(groupID: UUID | string, message: string): Promise<void>
{
if (typeof groupID === 'string')
return new Promise<void>((resolve, reject) =>
{
groupID = new UUID(groupID);
}
const circuit = this.circuit;
const agentName = this.agent.firstName + ' ' + this.agent.lastName;
const im: ImprovedInstantMessageMessage = new ImprovedInstantMessageMessage();
im.AgentData = {
AgentID: this.agent.agentID,
SessionID: circuit.sessionID
};
im.MessageBlock = {
FromGroup: false,
ToAgentID: groupID,
ParentEstateID: 0,
RegionID: UUID.zero(),
Position: Vector3.getZero(),
Offline: 0,
Dialog: InstantMessageDialog.SessionSend,
ID: groupID,
Timestamp: Math.floor(new Date().getTime() / 1000),
FromAgentName: Utils.StringToBuffer(agentName),
Message: Utils.StringToBuffer(message),
BinaryBucket: Utils.StringToBuffer('')
};
im.EstateBlock = {
EstateID: 0
};
const sequenceNo = circuit.sendMessage(im, PacketFlags.Reliable);
return circuit.waitForAck(sequenceNo, 10000);
this.startChatSession(groupID).then(() =>
{
console.log('Session joined');
if (typeof groupID === 'string')
{
groupID = new UUID(groupID);
}
const circuit = this.circuit;
const agentName = this.agent.firstName + ' ' + this.agent.lastName;
const im: ImprovedInstantMessageMessage = new ImprovedInstantMessageMessage();
im.AgentData = {
AgentID: this.agent.agentID,
SessionID: circuit.sessionID
};
im.MessageBlock = {
FromGroup: false,
ToAgentID: groupID,
ParentEstateID: 0,
RegionID: UUID.zero(),
Position: Vector3.getZero(),
Offline: 0,
Dialog: InstantMessageDialog.SessionSend,
ID: groupID,
Timestamp: Math.floor(new Date().getTime() / 1000),
FromAgentName: Utils.StringToBuffer(agentName),
Message: Utils.StringToBuffer(message),
BinaryBucket: Utils.StringToBuffer('')
};
im.EstateBlock = {
EstateID: 0
};
const sequenceNo = circuit.sendMessage(im, PacketFlags.Reliable);
return circuit.waitForAck(sequenceNo, 10000);
}).catch((err) =>
{
reject(err);
});
});
}
typeLocalMessage(message: string, thinkingTime?: number, charactersPerSecond?: number): Promise<void>