mirror of
https://github.com/icewind1991/mx-puppet-steam.git
synced 2026-06-03 09:34:13 +02:00
cleanups
This commit is contained in:
parent
e50ae56442
commit
cc607167ec
12 changed files with 3625 additions and 4351 deletions
10
README.md
10
README.md
|
|
@ -4,8 +4,12 @@ Matrix <-> Steam puppeting bridge based on [mx-puppet-bridge](https://github.com
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
The bridge is in early status, logging in and 1<->1 messages are mostly working.
|
- [x] login with steam guard support
|
||||||
Group messages are not working, typing status works somewhat.
|
- [x] 1 <->1 messaging
|
||||||
|
- [ ] group messaging
|
||||||
|
- [x] steam -> matrix typing notifications
|
||||||
|
- [x] online/offline status
|
||||||
|
- [x] retrieve nickname and avatar from steam
|
||||||
|
|
||||||
## Linking
|
## Linking
|
||||||
|
|
||||||
|
|
@ -15,4 +19,4 @@ Start a chat with @_steampuppet_bot:yourserver.com
|
||||||
link <username> <password>
|
link <username> <password>
|
||||||
```
|
```
|
||||||
|
|
||||||
If a steam guard (mobile or email) code is required you will be asked for the code.
|
If a steam guard (mobile or email) code is required, you will be asked for the code.
|
||||||
|
|
|
||||||
765
package-lock.json
generated
765
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -11,15 +11,12 @@
|
||||||
},
|
},
|
||||||
"author": "Icewind",
|
"author": "Icewind",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"body-parser": "^1.19.0",
|
|
||||||
"command-line-args": "^5.1.1",
|
"command-line-args": "^5.1.1",
|
||||||
"command-line-usage": "^5.0.5",
|
"command-line-usage": "^5.0.5",
|
||||||
"js-yaml": "^3.13.1",
|
"js-yaml": "^3.13.1",
|
||||||
"mx-puppet-bridge": "0.0.40",
|
"mx-puppet-bridge": "0.0.43",
|
||||||
"steam-user": "4.15.1",
|
"steam-user": "4.15.1",
|
||||||
"steamcommunity": "3.41.3",
|
|
||||||
"steamid": "1.1.3",
|
"steamid": "1.1.3",
|
||||||
"tslint": "^5.20.1",
|
|
||||||
"typescript": "^3.8.3"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -22,3 +22,10 @@ provisioning:
|
||||||
#sharedSecret: random string
|
#sharedSecret: random string
|
||||||
# Path prefix for the provisioning API. /v1 will be appended to the prefix automatically.
|
# Path prefix for the provisioning API. /v1 will be appended to the prefix automatically.
|
||||||
apiPrefix: /_matrix/provision
|
apiPrefix: /_matrix/provision
|
||||||
|
|
||||||
|
presence:
|
||||||
|
# Bridge Steam online/offline status
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
# How often to send status to the homeserver in milliseconds
|
||||||
|
interval: 5000
|
||||||
|
|
|
||||||
3423
src/@types/steam-user/enum.d.ts
vendored
3423
src/@types/steam-user/enum.d.ts
vendored
File diff suppressed because it is too large
Load diff
22
src/@types/steam-user/index.d.ts
vendored
22
src/@types/steam-user/index.d.ts
vendored
|
|
@ -1,22 +0,0 @@
|
||||||
// declare module 'steam-user' {
|
|
||||||
// export * from "steam-user-enums";
|
|
||||||
//
|
|
||||||
// export interface ILoginParams {
|
|
||||||
// accountName: string;
|
|
||||||
// password: string;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// export class Chat {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// export default class SteamUser {
|
|
||||||
// constructor();
|
|
||||||
//
|
|
||||||
// public logOn(params: any): void;
|
|
||||||
//
|
|
||||||
// public on(hook: string, callback: any): void;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
54
src/@types/steam-user/interfaces.d.ts
vendored
54
src/@types/steam-user/interfaces.d.ts
vendored
|
|
@ -1,54 +0,0 @@
|
||||||
declare module 'steam-user-interfaces' {
|
|
||||||
import {EChatEntryType, EChatRoomServerMessage} from "steam-user-enums";
|
|
||||||
import SteamId from "steamid";
|
|
||||||
|
|
||||||
export interface IIncomingFriendMessage {
|
|
||||||
steamid_friend: SteamId,
|
|
||||||
chat_entry_type: EChatEntryType,
|
|
||||||
from_limited_account: boolean,
|
|
||||||
message: string,
|
|
||||||
message_no_bbcode: string,
|
|
||||||
server_timestamp: Date,
|
|
||||||
ordinal: number,
|
|
||||||
local_echo: boolean,
|
|
||||||
low_priority: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IIncomingChatMessage {
|
|
||||||
chat_group_id: string,
|
|
||||||
chat_id: string,
|
|
||||||
steamid_sender: SteamId,
|
|
||||||
chat_entry_type: EChatEntryType,
|
|
||||||
from_limited_account: boolean,
|
|
||||||
message: string,
|
|
||||||
message_no_bbcode: string,
|
|
||||||
server_timestamp: Date,
|
|
||||||
ordinal: number,
|
|
||||||
mentions: IChatMentions | null,
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IChatMentions {
|
|
||||||
mention_all: boolean,
|
|
||||||
mention_here,
|
|
||||||
mention_steamids: SteamId[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IServerMessage {
|
|
||||||
message: EChatRoomServerMessage,
|
|
||||||
string_param?: string,
|
|
||||||
steamid_param?: SteamId
|
|
||||||
}
|
|
||||||
|
|
||||||
// incomplete
|
|
||||||
export interface IPersona {
|
|
||||||
player_name: string,
|
|
||||||
avatar_hash: Buffer,
|
|
||||||
last_logoff: Date,
|
|
||||||
last_logon: Date,
|
|
||||||
last_seen_online: Date,
|
|
||||||
game_name: string,
|
|
||||||
avatar_url_icon: string,
|
|
||||||
avatar_url_medium: string,
|
|
||||||
avatar_url_full: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
3421
src/enum.ts
Normal file
3421
src/enum.ts
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -7,15 +7,11 @@ import {
|
||||||
} from "mx-puppet-bridge";
|
} from "mx-puppet-bridge";
|
||||||
import * as commandLineArgs from "command-line-args";
|
import * as commandLineArgs from "command-line-args";
|
||||||
import * as commandLineUsage from "command-line-usage";
|
import * as commandLineUsage from "command-line-usage";
|
||||||
import * as escapeHtml from "escape-html";
|
|
||||||
import {Steam} from "./steam";
|
import {Steam} from "./steam";
|
||||||
import {NextcloudConfigWrap} from "./config";
|
import {NextcloudConfigWrap} from "./config";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import * as yaml from "js-yaml";
|
import * as yaml from "js-yaml";
|
||||||
import {GetDataFromStrHook, IPuppetData} from "mx-puppet-bridge/lib/src";
|
|
||||||
import * as SteamCommunity from 'steamcommunity';
|
|
||||||
import {LoginDetails, LoginToken} from "./login";
|
import {LoginDetails, LoginToken} from "./login";
|
||||||
import * as SteamID from "steamid";
|
|
||||||
import * as SteamUser from "steam-user";
|
import * as SteamUser from "steam-user";
|
||||||
|
|
||||||
const log = new Log("NextcloudPuppet:index");
|
const log = new Log("NextcloudPuppet:index");
|
||||||
|
|
@ -49,7 +45,7 @@ if (options.help) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const protocol = {
|
const protocol = {
|
||||||
features: {typingTimeout : 1 * 1000},
|
features: {typingTimeout : 1000, presence: true},
|
||||||
id: "steam",
|
id: "steam",
|
||||||
displayname: "Steam",
|
displayname: "Steam",
|
||||||
externalUrl: "https://steamcommunity.com/",
|
externalUrl: "https://steamcommunity.com/",
|
||||||
|
|
|
||||||
77
src/interfaces.ts
Normal file
77
src/interfaces.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
import SteamId from "steamid";
|
||||||
|
import {EPersonaState, EChatEntryType, EChatRoomServerMessage} from "./enum";
|
||||||
|
|
||||||
|
export interface IIncomingFriendMessage {
|
||||||
|
steamid_friend: SteamId,
|
||||||
|
chat_entry_type: EChatEntryType,
|
||||||
|
from_limited_account: boolean,
|
||||||
|
message: string,
|
||||||
|
message_no_bbcode: string,
|
||||||
|
server_timestamp: Date,
|
||||||
|
ordinal: number,
|
||||||
|
local_echo: boolean,
|
||||||
|
low_priority: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IIncomingChatMessage {
|
||||||
|
chat_group_id: string,
|
||||||
|
chat_id: string,
|
||||||
|
steamid_sender: SteamId,
|
||||||
|
chat_entry_type: EChatEntryType,
|
||||||
|
from_limited_account: boolean,
|
||||||
|
message: string,
|
||||||
|
message_no_bbcode: string,
|
||||||
|
server_timestamp: Date,
|
||||||
|
ordinal: number,
|
||||||
|
mentions: IChatMentions | null,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IChatMentions {
|
||||||
|
mention_all: boolean,
|
||||||
|
mention_here,
|
||||||
|
mention_steamids: SteamId[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IServerMessage {
|
||||||
|
message: EChatRoomServerMessage,
|
||||||
|
string_param?: string,
|
||||||
|
steamid_param?: SteamId
|
||||||
|
}
|
||||||
|
|
||||||
|
// incomplete
|
||||||
|
export interface IPersona {
|
||||||
|
persona_state: EPersonaState,
|
||||||
|
player_name: string,
|
||||||
|
avatar_hash: Buffer,
|
||||||
|
last_logoff: Date,
|
||||||
|
last_logon: Date,
|
||||||
|
last_seen_online: Date,
|
||||||
|
game_name: string,
|
||||||
|
gameid: string,
|
||||||
|
avatar_url_icon: string,
|
||||||
|
avatar_url_medium: string,
|
||||||
|
avatar_url_full: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AppInfo {
|
||||||
|
changenumber: number,
|
||||||
|
missingToken: boolean,
|
||||||
|
appinfo: {
|
||||||
|
appid: string,
|
||||||
|
common: {
|
||||||
|
name: string,
|
||||||
|
type: string,
|
||||||
|
releasestate: string,
|
||||||
|
oslist: string,
|
||||||
|
logo: string,
|
||||||
|
logo_small: string,
|
||||||
|
icon: string,
|
||||||
|
},
|
||||||
|
extended: {
|
||||||
|
developer: string,
|
||||||
|
publisher: string,
|
||||||
|
homepage: string,
|
||||||
|
listofdlc: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
102
src/steam.ts
102
src/steam.ts
|
|
@ -1,20 +1,17 @@
|
||||||
/// <reference path="@types/steam-user/enum.d.ts" />
|
|
||||||
/// <reference path="@types/steam-user/interfaces.d.ts" />
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PuppetBridge,
|
IFileEvent,
|
||||||
Log,
|
IMessageEvent,
|
||||||
IReceiveParams,
|
IReceiveParams,
|
||||||
IRemoteRoom,
|
IRemoteRoom,
|
||||||
IRemoteUser,
|
IRemoteUser,
|
||||||
IMessageEvent,
|
Log,
|
||||||
IFileEvent,
|
PuppetBridge,
|
||||||
Util,
|
|
||||||
IRetList,
|
|
||||||
} from "mx-puppet-bridge";
|
} from "mx-puppet-bridge";
|
||||||
import * as SteamUser from "steam-user";
|
import * as SteamUser from "steam-user";
|
||||||
import * as SteamID from "steamid";
|
import * as SteamID from "steamid";
|
||||||
import {IIncomingFriendMessage, IPersona} from "steam-user-interfaces";
|
import {EPersonaState} from "./enum";
|
||||||
|
import {MatrixPresence} from "mx-puppet-bridge/lib/src/presencehandler";
|
||||||
|
import {AppInfo, IIncomingFriendMessage, IPersona} from "./interfaces";
|
||||||
|
|
||||||
const log = new Log("MatrixPuppet:Steam");
|
const log = new Log("MatrixPuppet:Steam");
|
||||||
|
|
||||||
|
|
@ -23,6 +20,7 @@ interface ISteamPuppet {
|
||||||
data: any;
|
data: any;
|
||||||
sentEventIds: string[];
|
sentEventIds: string[];
|
||||||
knownPersonas: Map<string, IPersona>,
|
knownPersonas: Map<string, IPersona>,
|
||||||
|
knownApps: Map<string, AppInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ISteamPuppets {
|
interface ISteamPuppets {
|
||||||
|
|
@ -32,6 +30,7 @@ interface ISteamPuppets {
|
||||||
interface IPuppetParams {
|
interface IPuppetParams {
|
||||||
accountName: string,
|
accountName: string,
|
||||||
loginKey: string,
|
loginKey: string,
|
||||||
|
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,7 +45,7 @@ export class Steam {
|
||||||
|
|
||||||
async getPersona(p: ISteamPuppet, steamid: SteamID): Promise<IPersona> {
|
async getPersona(p: ISteamPuppet, steamid: SteamID): Promise<IPersona> {
|
||||||
let steamIdString = steamid.toString();
|
let steamIdString = steamid.toString();
|
||||||
let persona = p.knownPersonas.get(steamIdString)
|
let persona = p.knownPersonas.get(steamIdString);
|
||||||
if (persona) {
|
if (persona) {
|
||||||
return persona;
|
return persona;
|
||||||
} else if (p.client.users[steamIdString]) {
|
} else if (p.client.users[steamIdString]) {
|
||||||
|
|
@ -59,6 +58,18 @@ export class Steam {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getProduct(p: ISteamPuppet, appId: string): Promise<AppInfo> {
|
||||||
|
let app = p.knownApps.get(appId);
|
||||||
|
if (app) {
|
||||||
|
return app;
|
||||||
|
} else {
|
||||||
|
let {apps} = await p.client.getProductInfo([parseInt(appId, 10)], []);
|
||||||
|
let app = apps[appId];
|
||||||
|
p.knownApps.set(appId, app);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async getSendParams(puppetId: number, msg: IIncomingFriendMessage, fromSteamId?: SteamID): Promise<IReceiveParams> {
|
public async getSendParams(puppetId: number, msg: IIncomingFriendMessage, fromSteamId?: SteamID): Promise<IReceiveParams> {
|
||||||
const p = this.puppets[puppetId];
|
const p = this.puppets[puppetId];
|
||||||
|
|
||||||
|
|
@ -93,6 +104,7 @@ export class Steam {
|
||||||
sentEventIds: [],
|
sentEventIds: [],
|
||||||
typingUsers: {},
|
typingUsers: {},
|
||||||
knownPersonas: new Map(),
|
knownPersonas: new Map(),
|
||||||
|
knownApps: new Map(),
|
||||||
} as ISteamPuppet;
|
} as ISteamPuppet;
|
||||||
try {
|
try {
|
||||||
client.logOn({
|
client.logOn({
|
||||||
|
|
@ -101,18 +113,57 @@ export class Steam {
|
||||||
rememberPassword: true,
|
rememberPassword: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("user", (steamId, persona) => {
|
client.on("user", async (steamId, persona: IPersona) => {
|
||||||
this.puppets[puppetId].knownPersonas.set(steamId.toString(), persona);
|
const p = this.puppets[puppetId];
|
||||||
|
p.knownPersonas.set(steamId.toString(), persona);
|
||||||
|
|
||||||
|
let state: MatrixPresence = "offline";
|
||||||
|
|
||||||
|
switch (persona.persona_state) {
|
||||||
|
case EPersonaState.Away:
|
||||||
|
case EPersonaState.Busy:
|
||||||
|
case EPersonaState.Snooze:
|
||||||
|
state = "unavailable";
|
||||||
|
break;
|
||||||
|
case EPersonaState.LookingToPlay:
|
||||||
|
case EPersonaState.LookingToTrade:
|
||||||
|
case EPersonaState.Online:
|
||||||
|
state = "online";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (steamId.toString() != client.steamID.toString()) {
|
||||||
|
|
||||||
|
await this.bridge.setUserPresence({
|
||||||
|
puppetId,
|
||||||
|
userId: steamId.toString()
|
||||||
|
}, state);
|
||||||
|
|
||||||
|
if (persona.gameid && persona.gameid !== '0') {
|
||||||
|
let app = await this.getProduct(p, persona.gameid);
|
||||||
|
await this.bridge.setUserStatus({
|
||||||
|
puppetId,
|
||||||
|
userId: steamId.toString()
|
||||||
|
}, `Now playing: ${app.appinfo.common.name}`);
|
||||||
|
} else {
|
||||||
|
await this.bridge.setUserStatus({
|
||||||
|
puppetId,
|
||||||
|
userId: steamId.toString()
|
||||||
|
}, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("loggedOn", async (details) => {
|
client.on("loggedOn", async (details) => {
|
||||||
await this.bridge.setUserId(puppetId, client.steamID.toString());
|
await this.bridge.setUserId(puppetId, client.steamID.toString());
|
||||||
|
|
||||||
await this.bridge.sendStatusMessage(puppetId, `connected as ${details.vanity_url}(${client.steamID.toString()})!`);
|
await this.bridge.sendStatusMessage(puppetId, `connected as ${details.vanity_url}(${client.steamID.toString()})!`);
|
||||||
})
|
|
||||||
|
client.setPersona(EPersonaState.Away);
|
||||||
|
});
|
||||||
|
|
||||||
client.on("loginKey", (loginKey) => {
|
client.on("loginKey", (loginKey) => {
|
||||||
console.log("got new login key");
|
log.info("got new login key");
|
||||||
data.loginKey = loginKey;
|
data.loginKey = loginKey;
|
||||||
this.bridge.setPuppetData(puppetId, data);
|
this.bridge.setPuppetData(puppetId, data);
|
||||||
});
|
});
|
||||||
|
|
@ -125,7 +176,7 @@ export class Steam {
|
||||||
});
|
});
|
||||||
client.chat.on("friendTyping", (message: IIncomingFriendMessage) => {
|
client.chat.on("friendTyping", (message: IIncomingFriendMessage) => {
|
||||||
this.handleFriendTyping(puppetId, message);
|
this.handleFriendTyping(puppetId, message);
|
||||||
})
|
});
|
||||||
|
|
||||||
client.on("error", (err) => {
|
client.on("error", (err) => {
|
||||||
log.error(`Failed to start up puppet ${puppetId}`, err);
|
log.error(`Failed to start up puppet ${puppetId}`, err);
|
||||||
|
|
@ -171,7 +222,6 @@ export class Steam {
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async sendMessageToSteam(
|
public async sendMessageToSteam(
|
||||||
p: ISteamPuppet,
|
p: ISteamPuppet,
|
||||||
room: IRemoteRoom,
|
room: IRemoteRoom,
|
||||||
|
|
@ -179,22 +229,20 @@ export class Steam {
|
||||||
msg: string,
|
msg: string,
|
||||||
mediaId?: string,
|
mediaId?: string,
|
||||||
) {
|
) {
|
||||||
let id = "";
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let _roomSteamId = new SteamID(room.name as string);
|
let _roomSteamId = new SteamID(room.roomId as string);
|
||||||
if (_roomSteamId.isValid()) {
|
if (_roomSteamId.isValid()) {
|
||||||
const sendMessage = await p.client.chat.sendFriendMessage(room.roomId, msg);
|
const sendMessage = await p.client.chat.sendFriendMessage(room.roomId, msg);
|
||||||
id = `${sendMessage.server_timestamp.toISOString()}::${sendMessage.ordinal}`;
|
let id = `${sendMessage.server_timestamp.toISOString()}::${sendMessage.ordinal}`;
|
||||||
|
|
||||||
|
await this.bridge.eventSync.insert(room, eventId, id);
|
||||||
|
p.sentEventIds.push(id);
|
||||||
} else {
|
} else {
|
||||||
await this.bridge.sendStatusMessage(room.puppetId, `Sending group messages is currently not supported`);
|
await this.bridge.sendStatusMessage(room.puppetId, `Sending group messages is currently not supported`);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await this.bridge.sendStatusMessage(room.puppetId, `Sending group messages is currently not supported`);
|
await this.bridge.sendStatusMessage(room.puppetId, `Sending group messages is currently not supported`);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.bridge.eventSync.insert(room, eventId, id);
|
|
||||||
p.sentEventIds.push(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async handleMatrixMessage(room: IRemoteRoom, data: IMessageEvent, event: any) {
|
public async handleMatrixMessage(room: IRemoteRoom, data: IMessageEvent, event: any) {
|
||||||
|
|
@ -228,11 +276,15 @@ export class Steam {
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let persona = await this.getPersona(p, new SteamID(user.userId));
|
||||||
|
|
||||||
log.info(`Got request to create user ${user.userId}`);
|
log.info(`Got request to create user ${user.userId}`);
|
||||||
return {
|
return {
|
||||||
userId: user.userId,
|
userId: user.userId,
|
||||||
puppetId: user.puppetId,
|
puppetId: user.puppetId,
|
||||||
name: user.name,
|
name: persona.player_name,
|
||||||
|
avatarUrl: persona.avatar_url_medium
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
84
steamtest.ts
84
steamtest.ts
|
|
@ -1,84 +0,0 @@
|
||||||
import * as SteamUser from "steam-user";
|
|
||||||
import {log} from "util";
|
|
||||||
import SteamID = require("steamid");
|
|
||||||
const SteamCommunity = require('steamcommunity');
|
|
||||||
let community = new SteamCommunity();
|
|
||||||
|
|
||||||
let user = new SteamUser() as any;
|
|
||||||
|
|
||||||
function tryLogin(details): Promise<void> {
|
|
||||||
return new Promise((res, rej) => community.login(details, function(err) {
|
|
||||||
if (err) {
|
|
||||||
rej(err);
|
|
||||||
} else {
|
|
||||||
res();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
interface LoginDetails {
|
|
||||||
"accountName"?: string,
|
|
||||||
"password"?: string,
|
|
||||||
"steamguard"?: string,
|
|
||||||
"authCode"?: string,
|
|
||||||
"twoFactorCode"?: string,
|
|
||||||
"captcha"?: string,
|
|
||||||
"disableMobile"?: boolean,
|
|
||||||
}
|
|
||||||
|
|
||||||
interface LoginToken {
|
|
||||||
accountName: string,
|
|
||||||
webLoginToken: string,
|
|
||||||
steamID: SteamID
|
|
||||||
}
|
|
||||||
|
|
||||||
async function login(details: LoginDetails, steamGuard?: () => Promise<string>, twoFactor?: () => Promise<string>, captcha?: (url: string) => Promise<string>): Promise<LoginToken> {
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
await tryLogin(details);
|
|
||||||
return new Promise((res, rej) => community.getClientLogonToken((err, details) => {
|
|
||||||
if (err) {
|
|
||||||
rej(err);
|
|
||||||
} else {
|
|
||||||
res(details);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
} catch (e) {
|
|
||||||
switch (e.message) {
|
|
||||||
case 'SteamGuard':
|
|
||||||
if (steamGuard) {
|
|
||||||
details.steamguard = await steamGuard();
|
|
||||||
} else {
|
|
||||||
throw new Error("No steamguard handler provided")
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'SteamGuardMobile':
|
|
||||||
if (twoFactor) {
|
|
||||||
details.twoFactorCode = await twoFactor();
|
|
||||||
} else {
|
|
||||||
throw new Error("No twoFactor handler provided")
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'CAPTCHA':
|
|
||||||
if (captcha) {
|
|
||||||
details.captcha = await captcha(e.captchaurl);
|
|
||||||
} else {
|
|
||||||
throw new Error("No twoFactor handler provided")
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
let details = {
|
|
||||||
"accountName": "icewind1991",
|
|
||||||
"password": ""
|
|
||||||
};
|
|
||||||
console.log(await login(details, undefined, async () => "WM3MR"));
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue