diff --git a/src/commands/battle.ts b/src/commands/battle.ts new file mode 100644 index 0000000..78fce2d --- /dev/null +++ b/src/commands/battle.ts @@ -0,0 +1,68 @@ +import { BattleAvatar, BattleBuff, HeroPath, Item, ItemList, SceneBattleInfo, SceneMonsterWave, StartCocoonStageScRsp } from "../data/proto/StarRail"; +import Avatar from "../db/Avatar"; +import Inventory from "../db/Inventory"; +import Logger from "../util/Logger"; +import Interface, { Command } from "./Interface"; +const c = new Logger("/battle", "blue"); + +export default async function handle(command: Command) { + if (!Interface.target) { + c.log("No target specified"); + return; + } + + if (command.args.length == 0) { + c.log("Usage: /battle +"); + return; + } + + const player = Interface.target.player; + if (player.db.posData.planeID != 20101) { + c.log("For now, this is only confirmed to work on plane 20101, please teleport there first."); + } + + const inventory = await player.getInventory(); + const avatars = await Avatar.getAvatarsForLineup(player, player.db.lineup.lineups[player.db.lineup.curIndex]); + const monsters = command.args.map(arg => Number(arg)); + + Interface.target.send(StartCocoonStageScRsp, { + retcode: 0, + propEntityId: 0, + cocoonId: 1001, + wave: 0, + battleInfo: { + logicRandomSeed: 1, + stageId: 1022010, + monsterWaveList: [ + { monsterIdList: monsters, dropList: [{ itemList: [{ itemId: 102, num: 10 } as Item] } as ItemList] } as SceneMonsterWave + ], + battleAvatarList: avatars.map((avatar, i) => { + const equipment = inventory.getEquipmentByUid(avatar.db.equipmentUniqueId); + const equipData = (equipment) ? [{ + id: equipment.tid, + level: equipment.level, + promotion: equipment.promotion, + rank: equipment.rank + }] : []; + + return { + avatarType: avatar.db.avatarType, + equipmentList: equipData, + hp: avatar.db.fightProps.hp, + id: avatar.db.baseAvatarId, + sp: avatar.db.fightProps.sp, + index: i, + level: avatar.db.level, + promotion: avatar.db.promotion, + rank: avatar.db.rank, + relicList: [], + skilltreeList: [] + }; + }), + buffList: new Array(), + battleId: 0, + heroPathList: new Array(), + roundsLimit: 100 + } as SceneBattleInfo + } as StartCocoonStageScRsp); +} \ No newline at end of file diff --git a/src/commands/pos.ts b/src/commands/pos.ts new file mode 100644 index 0000000..407ed30 --- /dev/null +++ b/src/commands/pos.ts @@ -0,0 +1,13 @@ +import Logger from "../util/Logger"; +import Interface, { Command } from "./Interface"; +const c = new Logger("/pos", "blue"); + +export default async function handle(command: Command) { + if (!Interface.target) { + c.log("No target specified"); + return; + } + + const pos = Interface.target.player.db.posData.pos; + c.log(`Current position: x=${pos.x}, y=${pos.y}, z=${pos.z}.`); +} \ No newline at end of file diff --git a/src/server/packets/GetCurSceneInfoCsReq.ts b/src/server/packets/GetCurSceneInfoCsReq.ts index 1de7db7..0e02c65 100644 --- a/src/server/packets/GetCurSceneInfoCsReq.ts +++ b/src/server/packets/GetCurSceneInfoCsReq.ts @@ -1,5 +1,6 @@ -import { GetCurSceneInfoScRsp, MotionInfo, SceneEntityInfo, SceneNpcMonsterInfo, Vector } from "../../data/proto/StarRail"; +import { GetCurSceneInfoScRsp, MotionInfo, SceneEntityInfo, SceneNpcMonsterInfo, StartCocoonStageCsReq, Vector } from "../../data/proto/StarRail"; import { ActorEntity } from "../../game/entities/Actor"; +import { PropEntity } from "../../game/entities/Prop"; import MapEntryExcel from "../../util/excel/MapEntryExcel"; import MazePlaneExcel from "../../util/excel/MazePlaneExcel"; import Packet from "../kcp/Packet"; @@ -18,14 +19,15 @@ export default async function handle(session: Session, packet: Packet) { session.player.scene.spawnEntity(curAvatarEntity, true); session.player.scene.entryId = entryId; - // Send response. - session.send(GetCurSceneInfoScRsp, { + // Build response. + const dataObj : GetCurSceneInfoScRsp = { retcode: 0, scene: { planeId: posData.planeID, floorId: posData.floorID, entityList: [ - curAvatarEntity.getSceneEntityInfo() + curAvatarEntity.getSceneEntityInfo(), + ], lightenSectionList: [], leaderEntityId: curAvatarEntity.entityId, @@ -33,6 +35,9 @@ export default async function handle(session: Session, packet: Packet) { entryId: entryId, envBuffList: [], gameModeType: MazePlaneExcel.getGameModeForPlaneType(mazePlane.PlaneType), - }, - } as GetCurSceneInfoScRsp); + } + }; + + // Send response. + session.send(GetCurSceneInfoScRsp, dataObj); } \ No newline at end of file diff --git a/src/server/packets/PVEBattleResultCsReq.ts b/src/server/packets/PVEBattleResultCsReq.ts new file mode 100644 index 0000000..1ba2541 --- /dev/null +++ b/src/server/packets/PVEBattleResultCsReq.ts @@ -0,0 +1,34 @@ +import { BattleEndStatus, EnterMazeCsReq, EnterMazeScRsp, Item, ItemList, PVEBattleResultCsReq, PVEBattleResultScRsp } from "../../data/proto/StarRail"; +import MapEntryExcel from "../../util/excel/MapEntryExcel"; +import MazePlaneExcel from "../../util/excel/MazePlaneExcel"; +import Packet from "../kcp/Packet"; +import Session from "../kcp/Session"; + +export default async function handle(session: Session, packet: Packet) { + const body = packet.body as PVEBattleResultCsReq; + + // Add drops, for our little gambling addicts. + const inventory = await session.player.getInventory(); + inventory.addItem(102, 10); + await inventory.save(); + + // Build response. + const dataObj : PVEBattleResultScRsp = { + retcode: 0, + stageId: body.stageId, + curFinishChallenge: 0, + dropData: { itemList: [{ itemId: 102, num: 10 } as Item] } as ItemList, + extraDropData: { itemList: [{ itemId: 102, num: 10 } as Item] } as ItemList, + avatarExpReward: 0, + binVer: "", + resVer: "", + battleId: body.battleId, + endStatus: body.endStatus, + checkIdentical: true, + eventId: 0, + mismatchTurnCount: 0 + }; + + // Send response. + session.send(PVEBattleResultScRsp, dataObj); +} \ No newline at end of file