I don't want to talk about it. (#35)
This commit is contained in:
parent
fa7a364f88
commit
4738e7c44a
@ -13,6 +13,7 @@ export default async function handle(command: Command) {
|
|||||||
const actionType = command.args[0];
|
const actionType = command.args[0];
|
||||||
const avatarId = Number(command.args[1]);
|
const avatarId = Number(command.args[1]);
|
||||||
const uid = Interface.target.player.db._id;
|
const uid = Interface.target.player.db._id;
|
||||||
|
const player = Interface.target.player;
|
||||||
|
|
||||||
switch (actionType) {
|
switch (actionType) {
|
||||||
default: {
|
default: {
|
||||||
@ -20,21 +21,32 @@ export default async function handle(command: Command) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "add": {
|
case "add": {
|
||||||
if (!avatarId) return c.log("No avatarId specified");
|
if (!avatarId) {
|
||||||
|
return c.log("No avatarId specified");
|
||||||
|
}
|
||||||
|
|
||||||
// Check if it already exists
|
// Check if it already exists
|
||||||
const avatar = await Avatar.fromUID(uid, avatarId);
|
if (await Avatar.hasAvatar(player, avatarId)) {
|
||||||
if (avatar.length > 0) return c.log(`Avatar ${avatarId} already exists`);
|
return c.log(`Avatar ${avatarId} already exists`);
|
||||||
Avatar.create(uid, avatarId).then(a => c.log(`Avatar ${avatarId} added to ${a.ownerUid}`));
|
}
|
||||||
|
|
||||||
|
await Avatar.addAvatarToPlayer(player, avatarId).then(a => c.log(`Avatar ${avatarId} added to ${a.db.ownerUid}`));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "remove": {
|
case "remove": {
|
||||||
if (!avatarId) return c.log("No avatarId specified");
|
if (!avatarId) return c.log("No avatarId specified");
|
||||||
Avatar.remove(uid, avatarId).then(() => c.log(`Avatar ${avatarId} removed from ${uid}`));
|
await Avatar.removeAvatarFromPlayer(player, avatarId).then(() => c.log(`Avatar ${avatarId} removed from ${uid}`));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "giveall": {
|
case "giveall": {
|
||||||
for (const id in AvatarExcelTable) {
|
for (const id in AvatarExcelTable) {
|
||||||
await Avatar.create(uid, parseInt(id));
|
const avatarId = Number(id);
|
||||||
|
// Let's not brick our account.
|
||||||
|
if (avatarId>= 8000) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Avatar.addAvatarToPlayer(player, avatarId);
|
||||||
}
|
}
|
||||||
c.log(`All avatars added to ${uid}`);
|
c.log(`All avatars added to ${uid}`);
|
||||||
break;
|
break;
|
||||||
@ -42,7 +54,7 @@ export default async function handle(command: Command) {
|
|||||||
case "removeall": {
|
case "removeall": {
|
||||||
for (const id in AvatarExcelTable) {
|
for (const id in AvatarExcelTable) {
|
||||||
if (Number(id) !== 1001) {
|
if (Number(id) !== 1001) {
|
||||||
await Avatar.remove(uid, parseInt(id));
|
await Avatar.removeAvatarFromPlayer(player, parseInt(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.log(`All avatars removed from ${uid}`);
|
c.log(`All avatars removed from ${uid}`);
|
||||||
|
180
src/db/Avatar.ts
180
src/db/Avatar.ts
@ -1,68 +1,162 @@
|
|||||||
import { Avatar as AvatarI, AvatarType, LineupAvatar } from '../data/proto/StarRail';
|
// import { Avatar as AvatarI, AvatarType, LineupAvatar } from '../data/proto/StarRail';
|
||||||
|
import { AvatarSkillTree, AvatarType, EquipRelic, Avatar as AvatarProto } from '../data/proto/StarRail';
|
||||||
import Logger from '../util/Logger';
|
import Logger from '../util/Logger';
|
||||||
import Database from './Database';
|
import Database from './Database';
|
||||||
import Player, { LineupI } from './Player';
|
import Player, { LineupI } from './Player';
|
||||||
const c = new Logger("Avatar");
|
const c = new Logger("Avatar");
|
||||||
type UID = number | string;
|
type UID = number | string;
|
||||||
|
|
||||||
export default class Avatar {
|
interface AvatarI {
|
||||||
private constructor(public ownerUid: UID, public data: AvatarI, public lineup: LineupAvatar) {
|
ownerUid: number,
|
||||||
|
baseAvatarId: number,
|
||||||
|
avatarType: AvatarType,
|
||||||
|
level: number,
|
||||||
|
exp: number,
|
||||||
|
promotion: number,
|
||||||
|
rank: number,
|
||||||
|
equipmentUniqueId: number,
|
||||||
|
equipRelicList: EquipRelic[],
|
||||||
|
skilltreeList: AvatarSkillTree[],
|
||||||
|
fightProps: {
|
||||||
|
hp: number,
|
||||||
|
sp: number,
|
||||||
|
satiety: number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async create(uid: UID, baseAvatarId: number = 1001, slot: number = -1): Promise<Avatar> {
|
export default class Avatar {
|
||||||
|
public readonly player: Player;
|
||||||
|
public readonly db: AvatarI;
|
||||||
|
|
||||||
|
private constructor(player: Player, db: AvatarI) {
|
||||||
|
this.player = player;
|
||||||
|
this.db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
Create and fetch avatars from the database.
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
public static async loadAvatarsForPlayer(player: Player) : Promise<Avatar[]> {
|
||||||
|
// Read avatars for this player from the database.
|
||||||
const db = Database.getInstance();
|
const db = Database.getInstance();
|
||||||
// Check if already exists
|
const avatars = await db.getAll("avatars", { ownerUid: player.uid }) as unknown as AvatarI[];
|
||||||
const existing = await Avatar.fromUID(uid, baseAvatarId);
|
|
||||||
if (existing.length > 0) return existing[0];
|
// If this player doesn't have any avatars yet, add a default.
|
||||||
const avatar = new Avatar(uid, {
|
if (avatars.length < 1) {
|
||||||
baseAvatarId,
|
avatars.push({
|
||||||
equipmentUniqueId: 20003, // TODO: Placeholder while we work on inventory system
|
ownerUid: player.uid,
|
||||||
equipRelicList: [],
|
baseAvatarId: 1001,
|
||||||
exp: 0,
|
avatarType: AvatarType.AVATAR_FORMAL_TYPE,
|
||||||
level: 1,
|
level: 1,
|
||||||
|
exp: 1,
|
||||||
promotion: 1,
|
promotion: 1,
|
||||||
rank: 1,
|
rank: 1,
|
||||||
|
equipmentUniqueId: 20003,
|
||||||
|
equipRelicList: [],
|
||||||
skilltreeList: [],
|
skilltreeList: [],
|
||||||
}, {
|
fightProps: {
|
||||||
avatarType: AvatarType.AVATAR_FORMAL_TYPE,
|
|
||||||
hp: 10000,
|
hp: 10000,
|
||||||
id: baseAvatarId,
|
sp: 10000,
|
||||||
satiety: 100,
|
satiety: 100
|
||||||
slot: slot,
|
}
|
||||||
sp: 10000
|
} as AvatarI);
|
||||||
});
|
|
||||||
db.set("avatars", avatar);
|
|
||||||
return avatar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async fromUID(ownerUid: UID, baseAvatarId?: number): Promise<Avatar[]> {
|
// Construct Avatar instances.
|
||||||
const query = { ownerUid } as { ownerUid: UID, "data.baseAvatarId"?: number };
|
const res: Avatar[] = []
|
||||||
if (baseAvatarId) query['data.baseAvatarId'] = baseAvatarId;
|
for (const avatar of avatars) {
|
||||||
|
res.push(new Avatar(player, avatar));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done.
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async loadAvatarForPlayer(player: Player, baseAvatarId: number) : Promise<Avatar> {
|
||||||
|
// Fetch the given avatar from the database.
|
||||||
const db = Database.getInstance();
|
const db = Database.getInstance();
|
||||||
return await db.getAll("avatars", query) as unknown as Avatar[];
|
const avatar = await db.get("avatars", { ownerUid: player.uid, baseAvatarId: baseAvatarId }) as unknown as AvatarI;
|
||||||
|
|
||||||
|
// Sanity check.
|
||||||
|
if (!avatar) {
|
||||||
|
throw new Error(`Avatar ${baseAvatarId} does not exist for player ${player.uid}. This should never happen. Check your logic at the callsite.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async fromLineup(uid: UID, lineup: LineupI): Promise<Avatar[]> {
|
// Done.
|
||||||
try {
|
return new Avatar(player, avatar);
|
||||||
const avatarList: Array<Avatar> = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < lineup.avatarList.length; i++) {
|
|
||||||
const avatarId = lineup.avatarList[i];
|
|
||||||
const avatar = await Avatar.fromUID(uid, avatarId);
|
|
||||||
avatarList.push(avatar[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await Promise.all(avatarList);
|
public static async hasAvatar(player: Player, baseAvatarId: number) : Promise<boolean> {
|
||||||
} catch (e) {
|
// Fetch the given avatar from the database.
|
||||||
c.error(e as Error);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async remove(ownerUid: UID, baseAvatarId: number): Promise<void> {
|
|
||||||
const db = Database.getInstance();
|
const db = Database.getInstance();
|
||||||
await db.delete("avatars", { ownerUid, "data.baseAvatarId": baseAvatarId });
|
const avatar = await db.get("avatars", { ownerUid: player.uid, baseAvatarId: baseAvatarId }) as unknown as AvatarI;
|
||||||
|
|
||||||
|
// Return.
|
||||||
|
return avatar ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async addAvatarToPlayer(player: Player, baseAvatarId: number) : Promise<Avatar> {
|
||||||
|
const db = Database.getInstance();
|
||||||
|
|
||||||
|
// Make sure the player doesn't already have that avatar.
|
||||||
|
const existingAvatar = await db.get("avatars", { ownerUid: player.uid, baseAvatarId: baseAvatarId }) as unknown as AvatarI;
|
||||||
|
if (existingAvatar) {
|
||||||
|
return new Avatar(player, existingAvatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert.
|
||||||
|
const data : AvatarI = {
|
||||||
|
ownerUid: player.uid,
|
||||||
|
baseAvatarId: baseAvatarId,
|
||||||
|
avatarType: AvatarType.AVATAR_FORMAL_TYPE,
|
||||||
|
level: 1,
|
||||||
|
exp: 1,
|
||||||
|
promotion: 1,
|
||||||
|
rank: 1,
|
||||||
|
equipmentUniqueId: 20003,
|
||||||
|
equipRelicList: [],
|
||||||
|
skilltreeList: [],
|
||||||
|
fightProps: {
|
||||||
|
hp: 10000,
|
||||||
|
sp: 10000,
|
||||||
|
satiety: 100
|
||||||
|
}
|
||||||
|
};
|
||||||
|
await db.set("avatars", data);
|
||||||
|
return new Avatar(player, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async removeAvatarFromPlayer(player: Player, baseAvatarId: number) {
|
||||||
|
const db = Database.getInstance();
|
||||||
|
await db.delete("avatars", { ownerUid: player.uid, baseAvatarId: baseAvatarId });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async getAvatarsForLineup(player: Player, lineup: LineupI) : Promise<Avatar[]> {
|
||||||
|
const res: Avatar[] = [];
|
||||||
|
|
||||||
|
// Load all avatars in this lineup.
|
||||||
|
for (const avatarId of lineup.avatarList) {
|
||||||
|
res.push(await Avatar.loadAvatarForPlayer(player, avatarId));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done.
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
Get avatar info.
|
||||||
|
********************************************************************************/
|
||||||
|
public asAvatarProto() : AvatarProto {
|
||||||
|
return {
|
||||||
|
baseAvatarId: this.db.baseAvatarId,
|
||||||
|
exp: this.db.exp,
|
||||||
|
level: this.db.level,
|
||||||
|
promotion: this.db.promotion,
|
||||||
|
rank: this.db.rank,
|
||||||
|
skilltreeList: this.db.skilltreeList,
|
||||||
|
equipmentUniqueId: this.db.equipmentUniqueId,
|
||||||
|
equipRelicList: this.db.equipRelicList
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
@ -28,7 +28,7 @@ export default class Database {
|
|||||||
const _collection = db.collection(collection);
|
const _collection = db.collection(collection);
|
||||||
if (!(await db.listCollections({ name: collection }).toArray()).length) {
|
if (!(await db.listCollections({ name: collection }).toArray()).length) {
|
||||||
c.warn(`Collection ${collection} does not exist. Creating...`);
|
c.warn(`Collection ${collection} does not exist. Creating...`);
|
||||||
await _collection.createIndexes([{ key: { id: 1 }, unique: true }]);
|
await _collection.createIndexes([{ key: { _id: 1 } }]);
|
||||||
}
|
}
|
||||||
const result = query ? await _collection.findOne(query) : await _collection.findOne();
|
const result = query ? await _collection.findOne(query) : await _collection.findOne();
|
||||||
return result;
|
return result;
|
||||||
@ -44,7 +44,7 @@ export default class Database {
|
|||||||
const _collection = db.collection(collection);
|
const _collection = db.collection(collection);
|
||||||
if (!(await db.listCollections({ name: collection }).toArray()).length) {
|
if (!(await db.listCollections({ name: collection }).toArray()).length) {
|
||||||
c.warn(`Collection ${collection} does not exist. Creating...`);
|
c.warn(`Collection ${collection} does not exist. Creating...`);
|
||||||
await _collection.createIndexes([{ key: { id: 1 }, unique: true }]);
|
await _collection.createIndexes([{ key: { _id: 1 } }]);
|
||||||
}
|
}
|
||||||
const result = query ? await _collection.find(query).toArray() : await _collection.find().toArray();
|
const result = query ? await _collection.find(query).toArray() : await _collection.find().toArray();
|
||||||
return result;
|
return result;
|
||||||
@ -60,10 +60,12 @@ export default class Database {
|
|||||||
const _collection = db.collection(collection);
|
const _collection = db.collection(collection);
|
||||||
if (!(await db.listCollections({ name: collection }).toArray()).length) {
|
if (!(await db.listCollections({ name: collection }).toArray()).length) {
|
||||||
c.warn(`Collection ${collection} does not exist. Creating...`);
|
c.warn(`Collection ${collection} does not exist. Creating...`);
|
||||||
await _collection.createIndexes([{ key: { id: 1 }, unique: true }]);
|
await _collection.createIndexes([{ key: { _id: 1 } }]);
|
||||||
}
|
}
|
||||||
return await _collection.insertOne(payload);
|
return await _collection.insertOne(payload);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
c.error("In set.")
|
||||||
|
c.error(payload)
|
||||||
c.error(e as Error);
|
c.error(e as Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,7 +76,7 @@ export default class Database {
|
|||||||
const _collection = db.collection(collection);
|
const _collection = db.collection(collection);
|
||||||
if (!(await db.listCollections({ name: collection }).toArray()).length) {
|
if (!(await db.listCollections({ name: collection }).toArray()).length) {
|
||||||
c.warn(`Collection ${collection} does not exist. Creating...`);
|
c.warn(`Collection ${collection} does not exist. Creating...`);
|
||||||
await _collection.createIndexes([{ key: { id: 1 }, unique: true }]);
|
await _collection.createIndexes([{ key: { _id: 1 } }]);
|
||||||
}
|
}
|
||||||
return await _collection.deleteOne(query);
|
return await _collection.deleteOne(query);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -88,7 +90,7 @@ export default class Database {
|
|||||||
const _collection = db.collection(collection);
|
const _collection = db.collection(collection);
|
||||||
if (!(await db.listCollections({ name: collection }).toArray()).length) {
|
if (!(await db.listCollections({ name: collection }).toArray()).length) {
|
||||||
c.warn(`Collection ${collection} does not exist. Creating...`);
|
c.warn(`Collection ${collection} does not exist. Creating...`);
|
||||||
await _collection.createIndexes([{ key: { id: 1 }, unique: true }]);
|
await _collection.createIndexes([{ key: { _id: 1 } }]);
|
||||||
}
|
}
|
||||||
return await _collection.updateOne(query, { $set: payload }, { upsert: true });
|
return await _collection.updateOne(query, { $set: payload }, { upsert: true });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -3,7 +3,6 @@ import Logger from "../util/Logger";
|
|||||||
import Database from "./Database";
|
import Database from "./Database";
|
||||||
import Player from "./Player";
|
import Player from "./Player";
|
||||||
import ItemExcel from "../util/excel/ItemExcel";
|
import ItemExcel from "../util/excel/ItemExcel";
|
||||||
import { Timestamp } from "mongodb";
|
|
||||||
|
|
||||||
const c = new Logger("Inventory");
|
const c = new Logger("Inventory");
|
||||||
|
|
||||||
@ -165,10 +164,6 @@ export default class Inventory {
|
|||||||
if (!itemData || itemData.ItemType != "Material") {
|
if (!itemData || itemData.ItemType != "Material") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const t = itemData.ItemType;
|
|
||||||
if (t != "Material") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get current item count for this ID and calculate new count.
|
// Get current item count for this ID and calculate new count.
|
||||||
const currentCount = this.db.materials[id] ?? 0;
|
const currentCount = this.db.materials[id] ?? 0;
|
||||||
@ -189,6 +184,11 @@ export default class Inventory {
|
|||||||
public async addEquipment(equipment: number | Equipment) {
|
public async addEquipment(equipment: number | Equipment) {
|
||||||
// If the parameter is a number, add a new equipment with this item ID as base.
|
// If the parameter is a number, add a new equipment with this item ID as base.
|
||||||
if (typeof(equipment) == "number") {
|
if (typeof(equipment) == "number") {
|
||||||
|
// Sanity check.
|
||||||
|
if (ItemExcel.fromId(equipment)?.ItemType != "Equipment") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const equip : Equipment = {
|
const equip : Equipment = {
|
||||||
tid: equipment,
|
tid: equipment,
|
||||||
uniqueId: this.db.nextItemUid++,
|
uniqueId: this.db.nextItemUid++,
|
||||||
@ -292,6 +292,9 @@ export default class Inventory {
|
|||||||
// Find index to delete.
|
// Find index to delete.
|
||||||
const toDelete: number = (typeof(equipment) == "number") ? equipment : equipment.uniqueId;
|
const toDelete: number = (typeof(equipment) == "number") ? equipment : equipment.uniqueId;
|
||||||
const index = this.db.equipments.findIndex(i => i.uniqueId == toDelete);
|
const index = this.db.equipments.findIndex(i => i.uniqueId == toDelete);
|
||||||
|
if (index == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Delete and save.
|
// Delete and save.
|
||||||
this.db.equipments.splice(index, 1);
|
this.db.equipments.splice(index, 1);
|
||||||
@ -309,6 +312,9 @@ export default class Inventory {
|
|||||||
// Find index to delete.
|
// Find index to delete.
|
||||||
const toDelete: number = (typeof(relic) == "number") ? relic : relic.uniqueId;
|
const toDelete: number = (typeof(relic) == "number") ? relic : relic.uniqueId;
|
||||||
const index = this.db.relics.findIndex(i => i.uniqueId == toDelete);
|
const index = this.db.relics.findIndex(i => i.uniqueId == toDelete);
|
||||||
|
if (index == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Delete and save.
|
// Delete and save.
|
||||||
this.db.relics.splice(index, 1);
|
this.db.relics.splice(index, 1);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Session from "../server/kcp/Session";
|
import Session from "../server/kcp/Session";
|
||||||
import { AvatarType, ExtraLineupType, HeroBasicType, LineupInfo, Vector } from "../data/proto/StarRail";
|
import { AvatarType, ExtraLineupType, HeroBasicType, LineupAvatar, LineupInfo, Vector } from "../data/proto/StarRail";
|
||||||
import Logger from "../util/Logger";
|
import Logger from "../util/Logger";
|
||||||
import Account from "./Account";
|
import Account from "./Account";
|
||||||
import Avatar from "./Avatar";
|
import Avatar from "./Avatar";
|
||||||
@ -67,34 +67,35 @@ export default class Player {
|
|||||||
|
|
||||||
public static async fromToken(session: Session, token: string): Promise<Player | undefined> {
|
public static async fromToken(session: Session, token: string): Promise<Player | undefined> {
|
||||||
const db = Database.getInstance();
|
const db = Database.getInstance();
|
||||||
const plr = await db.get("players", { token }) as unknown as PlayerI;
|
const plr = await db.get("players", { token: token }) as unknown as PlayerI;
|
||||||
if (!plr) return Player.fromUID(session, (await Account.fromToken(token))?.uid || Math.round(Math.random() * 50000));
|
if (!plr) return await Player.fromUID(session, (await Account.fromToken(token))?.uid || Math.round(Math.random() * 50000));
|
||||||
|
|
||||||
return new Player(session, plr);
|
return new Player(session, plr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getLineup(lineupIndex?: number): Promise<LineupInfo> {
|
public async getLineup(lineupIndex?: number): Promise<LineupInfo> {
|
||||||
const curIndex = this.db.lineup.curIndex;
|
// Get avatar data.
|
||||||
const lineup = this.db.lineup.lineups[lineupIndex || curIndex];
|
const index = lineupIndex ?? this.db.lineup.curIndex;
|
||||||
const avatars = await Avatar.fromLineup(this.uid, lineup);
|
const lineup = this.db.lineup.lineups[index];
|
||||||
let slot = 0;
|
const avatars = await Avatar.getAvatarsForLineup(this, lineup);
|
||||||
avatars.forEach(avatar => {
|
|
||||||
// Fallback lineup
|
// Construct LineupInfo.
|
||||||
if (!avatar) return; // Matsuko.
|
const lineupAvatars : LineupAvatar[] = [];
|
||||||
if (!avatar.lineup) avatar.lineup = {
|
for (let slot = 0; slot < avatars.length; slot++) {
|
||||||
avatarType: AvatarType.AVATAR_FORMAL_TYPE,
|
lineupAvatars.push({
|
||||||
hp: 10000,
|
|
||||||
id: 1001,
|
|
||||||
satiety: 100,
|
|
||||||
slot: slot,
|
slot: slot,
|
||||||
sp: 10000
|
avatarType: avatars[slot].db.avatarType,
|
||||||
}
|
id: avatars[slot].db.baseAvatarId,
|
||||||
avatar.lineup.slot = slot++;
|
hp: avatars[slot].db.fightProps.hp,
|
||||||
|
sp: avatars[slot].db.fightProps.sp,
|
||||||
|
satiety: avatars[slot].db.fightProps.satiety
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...lineup,
|
...lineup,
|
||||||
index: 0,
|
index: 0,
|
||||||
avatarList: avatars.map(x => x.lineup)
|
avatarList: lineupAvatars
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,23 +167,26 @@ export default class Player {
|
|||||||
name: "",
|
name: "",
|
||||||
planeId: 10001
|
planeId: 10001
|
||||||
}
|
}
|
||||||
|
|
||||||
const LINEUPS = 6;
|
const LINEUPS = 6;
|
||||||
dataObj.lineup = {
|
for (let i = 0; i < LINEUPS; i++) {
|
||||||
curIndex: 0,
|
const copy = {
|
||||||
lineups: {}
|
...baseLineup,
|
||||||
}
|
index: 0,
|
||||||
for (let i = 0; i <= LINEUPS; i++) {
|
name: `Team ${i}`
|
||||||
const copy = baseLineup;
|
};
|
||||||
copy.index = 0;
|
|
||||||
copy.name = `Team ${i}`;
|
|
||||||
dataObj.lineup.lineups[i] = copy;
|
dataObj.lineup.lineups[i] = copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Avatar.create(uid, 1001, 0);
|
const player = new Player(session, dataObj);
|
||||||
|
|
||||||
|
await Avatar.addAvatarToPlayer(player, 1001);
|
||||||
|
// await Avatar.create(uid, 1001, 0);
|
||||||
|
|
||||||
|
|
||||||
|
// Save to database and return.
|
||||||
await db.set("players", dataObj);
|
await db.set("players", dataObj);
|
||||||
return new Player(session, dataObj);
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async save() {
|
public async save() {
|
||||||
|
@ -55,7 +55,7 @@ export default class Session {
|
|||||||
if (!recv) break;
|
if (!recv) break;
|
||||||
|
|
||||||
if (Packet.isValid(recv)) {
|
if (Packet.isValid(recv)) {
|
||||||
this.handlePacket(new Packet(recv));
|
await this.handlePacket(new Packet(recv));
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (recv)
|
} while (recv)
|
||||||
@ -68,8 +68,8 @@ export default class Session {
|
|||||||
this.c.verbL(packet.body);
|
this.c.verbL(packet.body);
|
||||||
this.c.verbH(packet.rawData);
|
this.c.verbH(packet.rawData);
|
||||||
|
|
||||||
import(`../packets/${packet.protoName}`).then(mod => {
|
await import(`../packets/${packet.protoName}`).then(async mod => {
|
||||||
mod.default(this, packet);
|
await mod.default(this, packet);
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
if (e.code === 'MODULE_NOT_FOUND') this.c.warn(`Unhandled packet: ${packet.protoName}`);
|
if (e.code === 'MODULE_NOT_FOUND') this.c.warn(`Unhandled packet: ${packet.protoName}`);
|
||||||
else this.c.error(e);
|
else this.c.error(e);
|
||||||
@ -79,12 +79,13 @@ export default class Session {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async sync() {
|
public async sync() {
|
||||||
const avatars = await Avatar.fromUID(this.player.db._id);
|
const avatars = await Avatar.loadAvatarsForPlayer(this.player);
|
||||||
|
//const avatars = await Avatar.fromUID(this.player.db._id);
|
||||||
const inventory = await this.player.getInventory();
|
const inventory = await this.player.getInventory();
|
||||||
|
|
||||||
this.send(PlayerSyncScNotify, PlayerSyncScNotify.fromPartial({
|
this.send(PlayerSyncScNotify, PlayerSyncScNotify.fromPartial({
|
||||||
avatarSync: {
|
avatarSync: {
|
||||||
avatarList: avatars.map(x => x.data)
|
avatarList: avatars.map(x => x.asAvatarProto())
|
||||||
},
|
},
|
||||||
materialList: inventory.getMaterialList(),
|
materialList: inventory.getMaterialList(),
|
||||||
equipmentList: inventory.getEquipmentList(),
|
equipmentList: inventory.getEquipmentList(),
|
||||||
|
@ -1,26 +1,19 @@
|
|||||||
import { GetAvatarDataCsReq, GetAvatarDataScRsp } from "../../data/proto/StarRail";
|
import { GetAvatarDataCsReq, GetAvatarDataScRsp } from "../../data/proto/StarRail";
|
||||||
import AvatarExcelTable from "../../data/excel/AvatarExcelTable.json";
|
|
||||||
import Packet from "../kcp/Packet";
|
import Packet from "../kcp/Packet";
|
||||||
import Session from "../kcp/Session";
|
import Session from "../kcp/Session";
|
||||||
import AvatarDb from "../../db/Avatar";
|
import AvatarDb from "../../db/Avatar";
|
||||||
|
|
||||||
import { Avatar } from "../../data/proto/StarRail";
|
|
||||||
|
|
||||||
export default async function handle(session: Session, packet: Packet) {
|
export default async function handle(session: Session, packet: Packet) {
|
||||||
const body = packet.body as GetAvatarDataCsReq;
|
const body = packet.body as GetAvatarDataCsReq;
|
||||||
|
const avatars = await AvatarDb.loadAvatarsForPlayer(session.player);
|
||||||
|
|
||||||
const avatar = await AvatarDb.fromUID(session.player.db._id);
|
|
||||||
|
|
||||||
console.log(avatar.length)
|
|
||||||
const dataObj = {
|
const dataObj = {
|
||||||
retcode: 0,
|
retcode: 0,
|
||||||
avatarList: avatar.map(av => Avatar.fromPartial(av.data)),
|
avatarList: avatars.map(av => av.asAvatarProto()),
|
||||||
isAll: body.isGetAll
|
isAll: body.isGetAll
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.values(AvatarExcelTable).forEach(avatar => {
|
// Make sure we wait for this to send.
|
||||||
// dataObj.avatarList.push()
|
// GetAvatarDataScRsp HAS to be sent immediately after the Req.
|
||||||
});
|
await session.send(GetAvatarDataScRsp, dataObj);
|
||||||
|
|
||||||
session.send(GetAvatarDataScRsp, dataObj);
|
|
||||||
}
|
}
|
@ -1,39 +1,12 @@
|
|||||||
import { AvatarType, ExtraLineupType, GetCurLineupDataScRsp } from "../../data/proto/StarRail";
|
import { AvatarType, ExtraLineupType, GetCurLineupDataScRsp } from "../../data/proto/StarRail";
|
||||||
import Avatar from "../../db/Avatar";
|
|
||||||
import Packet from "../kcp/Packet";
|
import Packet from "../kcp/Packet";
|
||||||
import Session from "../kcp/Session";
|
import Session from "../kcp/Session";
|
||||||
|
|
||||||
export default async function handle(session: Session, packet: Packet) {
|
export default async function handle(session: Session, packet: Packet) {
|
||||||
let lineup = await session.player.getLineup();
|
let lineup = await session.player.getLineup();
|
||||||
|
|
||||||
// This is a HORRIBLE solution, but tbh I just can't reproduce the bug so:
|
|
||||||
if (!lineup) {
|
|
||||||
session.c.error("Error! lineup is undefined. Falling back to default lineup.", false);
|
|
||||||
lineup = {
|
|
||||||
avatarList: [{
|
|
||||||
avatarType: AvatarType.AVATAR_FORMAL_TYPE,
|
|
||||||
hp: 10000,
|
|
||||||
id: 1001,
|
|
||||||
sp: 10000,
|
|
||||||
satiety: 100,
|
|
||||||
slot: 0,
|
|
||||||
}],
|
|
||||||
extraLineupType: ExtraLineupType.LINEUP_NONE,
|
|
||||||
index: 0,
|
|
||||||
isVirtual: false,
|
|
||||||
leaderSlot: 0,
|
|
||||||
mp: 100,
|
|
||||||
planeId: 10001,
|
|
||||||
name: "Fallback"
|
|
||||||
}
|
|
||||||
session.player.setLineup(lineup, 0, 0);
|
|
||||||
session.player.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
session.send(GetCurLineupDataScRsp, {
|
session.send(GetCurLineupDataScRsp, {
|
||||||
retcode: 0,
|
retcode: 0,
|
||||||
lineup: {
|
lineup: lineup
|
||||||
...lineup,
|
|
||||||
}
|
|
||||||
} as GetCurLineupDataScRsp);
|
} as GetCurLineupDataScRsp);
|
||||||
}
|
}
|
@ -8,9 +8,16 @@ export default async function handle(session: Session, packet: Packet) {
|
|||||||
const body = packet.body as JoinLineupCsReq;
|
const body = packet.body as JoinLineupCsReq;
|
||||||
session.send(JoinLineupScRsp, { retcode: 0 });
|
session.send(JoinLineupScRsp, { retcode: 0 });
|
||||||
|
|
||||||
|
// Replace avatar in the player's lineup.
|
||||||
|
const slot = body.slot ?? 0;
|
||||||
|
session.player.db.lineup.lineups[session.player.db.lineup.curIndex].avatarList[slot] = body.baseAvatarId;
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
let lineup = await session.player.getLineup();
|
let lineup = await session.player.getLineup();
|
||||||
const slot = body.slot || 0;
|
|
||||||
const avatarList = [];
|
const avatarList = [];
|
||||||
|
|
||||||
|
// What in the fuck is the purpose of this loop supposed to be?!
|
||||||
for (const avatarId in lineup) {
|
for (const avatarId in lineup) {
|
||||||
const avatar = await Avatar.fromUID(session.player.db._id, Number(avatarId));
|
const avatar = await Avatar.fromUID(session.player.db._id, Number(avatarId));
|
||||||
if (avatar.length === 0) return session.c.warn(`Avatar ${body.baseAvatarId} not found`);
|
if (avatar.length === 0) return session.c.warn(`Avatar ${body.baseAvatarId} not found`);
|
||||||
@ -27,10 +34,12 @@ export default async function handle(session: Session, packet: Packet) {
|
|||||||
};
|
};
|
||||||
if (body.extraLineupType) lineup.extraLineupType = body.extraLineupType;
|
if (body.extraLineupType) lineup.extraLineupType = body.extraLineupType;
|
||||||
session.player.setLineup(lineup);
|
session.player.setLineup(lineup);
|
||||||
|
*/
|
||||||
|
|
||||||
session.player.save();
|
session.player.save();
|
||||||
|
|
||||||
session.send(SyncLineupNotify, {
|
session.send(SyncLineupNotify, {
|
||||||
lineup: lineup,
|
lineup: await session.player.getLineup(),
|
||||||
reasonList: [SyncLineupReason.SYNC_REASON_NONE]
|
reasonList: [SyncLineupReason.SYNC_REASON_NONE]
|
||||||
} as SyncLineupNotify);
|
} as SyncLineupNotify);
|
||||||
}
|
}
|
@ -45,7 +45,8 @@ export default async function handle(session: Session, packet: Packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!plr.db.lineup) {
|
if (!plr.db.lineup) {
|
||||||
await Avatar.create(plr.db._id, 1001, 0);
|
await Avatar.addAvatarToPlayer(plr, 1001);
|
||||||
|
//await Avatar.create(plr.db._id, 1001, 0);
|
||||||
const baseLineup = {
|
const baseLineup = {
|
||||||
avatarList: [1001],
|
avatarList: [1001],
|
||||||
extraLineupType: ExtraLineupType.LINEUP_NONE,
|
extraLineupType: ExtraLineupType.LINEUP_NONE,
|
||||||
|
Loading…
Reference in New Issue
Block a user