145 lines
3.8 KiB
TypeScript
145 lines
3.8 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { ByteWriter } from '../../src/netproto/core/byte-writer.ts'
|
|
import {
|
|
decodeD2gsS2cPacket,
|
|
decodeD2gsServerPacket,
|
|
S2C_PACKET_SIZES,
|
|
} from '../../src/netproto/index.ts'
|
|
|
|
describe('D2GS S->C 1.13c packet decoders (M1)', () => {
|
|
it('decodes 0x09 AssignWarp with warpId populated on UnitSnapshot', () => {
|
|
const w = new ByteWriter(S2C_PACKET_SIZES[0x09]!)
|
|
w.u8(0x09)
|
|
w.u8(5) // unitType = tile
|
|
w.u32LE(300) // unitId
|
|
w.u8(18) // warpId / classId
|
|
w.u16LE(5100)
|
|
w.u16LE(5200)
|
|
const ev = decodeD2gsServerPacket(w.toUint8Array())
|
|
expect(ev.type).toBe('UnitAssign')
|
|
if (ev.type === 'UnitAssign') {
|
|
expect(ev.unit.unitType).toBe(5)
|
|
expect(ev.unit.id).toBe(300)
|
|
expect(ev.unit.classId).toBe(18)
|
|
expect(ev.unit.warpId).toBe(18)
|
|
expect(ev.unit.x).toBe(5100)
|
|
expect(ev.unit.y).toBe(5200)
|
|
}
|
|
})
|
|
|
|
it('decodes 0x27 NPCInfo, 0x91 NPCGetShow, and 0xAB NPCHeal', () => {
|
|
const w27 = new ByteWriter(S2C_PACKET_SIZES[0x27]!)
|
|
w27.u8(0x27)
|
|
w27.u8(1)
|
|
w27.u32LE(44)
|
|
w27.bytes(new Uint8Array(34))
|
|
const ev27 = decodeD2gsS2cPacket(w27.toUint8Array())
|
|
expect(ev27).toMatchObject({ type: 'Npc', kind: 'info', npcId: 44 })
|
|
|
|
const w91 = new ByteWriter(S2C_PACKET_SIZES[0x91]!)
|
|
w91.u8(0x91)
|
|
w91.u8(0)
|
|
w91.u32LE(44)
|
|
w91.bytes(new Uint8Array(20))
|
|
const ev91 = decodeD2gsS2cPacket(w91.toUint8Array())
|
|
expect(ev91).toMatchObject({ type: 'Npc', kind: 'menu', npcId: 44 })
|
|
|
|
const wab = new ByteWriter(S2C_PACKET_SIZES[0xab]!)
|
|
wab.u8(0xab)
|
|
wab.u8(1)
|
|
wab.u32LE(44)
|
|
wab.u8(120)
|
|
const evab = decodeD2gsS2cPacket(wab.toUint8Array())
|
|
expect(evab).toEqual({ type: 'Npc', kind: 'heal', npcId: 44, result: 120 })
|
|
})
|
|
|
|
it('decodes 0x4E MercForHire, 0x4F StartMercList, 0x81 MercAssign, and 0x9B MercReviveCost', () => {
|
|
const w4f = new ByteWriter(1)
|
|
w4f.u8(0x4f)
|
|
expect(decodeD2gsS2cPacket(w4f.toUint8Array())).toEqual({
|
|
type: 'Merc',
|
|
kind: 'hireList',
|
|
})
|
|
|
|
const w4e = new ByteWriter(7)
|
|
w4e.u8(0x4e)
|
|
w4e.u16LE(14)
|
|
w4e.u32LE(0x12345678)
|
|
expect(decodeD2gsS2cPacket(w4e.toUint8Array())).toEqual({
|
|
type: 'Merc',
|
|
kind: 'hireList',
|
|
nameId: 14,
|
|
value: 0x12345678,
|
|
})
|
|
|
|
const w81 = new ByteWriter(20)
|
|
w81.u8(0x81)
|
|
w81.u8(0)
|
|
w81.u16LE(271)
|
|
w81.u32LE(1)
|
|
w81.u32LE(99)
|
|
w81.u32LE(0xdeadbeef)
|
|
w81.u32LE(0)
|
|
expect(decodeD2gsS2cPacket(w81.toUint8Array())).toEqual({
|
|
type: 'Merc',
|
|
kind: 'assign',
|
|
ownerId: 1,
|
|
mercId: 99,
|
|
classId: 271,
|
|
value: 0xdeadbeef,
|
|
})
|
|
|
|
const w9b = new ByteWriter(7)
|
|
w9b.u8(0x9b)
|
|
w9b.u16LE(14)
|
|
w9b.u32LE(25000)
|
|
expect(decodeD2gsS2cPacket(w9b.toUint8Array())).toEqual({
|
|
type: 'Merc',
|
|
kind: 'stat',
|
|
nameId: 14,
|
|
value: 25000,
|
|
})
|
|
})
|
|
|
|
it('decodes 0x77 ButtonActions, 0x78 TradeAccepted (with partnerName), 0x79 GoldInTrade, and 0x92 ClearDisplay', () => {
|
|
const w77 = new ByteWriter(2)
|
|
w77.u8(0x77)
|
|
w77.u8(0x01)
|
|
expect(decodeD2gsS2cPacket(w77.toUint8Array())).toEqual({
|
|
type: 'Trade',
|
|
action: 0x01,
|
|
})
|
|
|
|
const w78 = new ByteWriter(21)
|
|
w78.u8(0x78)
|
|
w78.fixedCString('TradeBuddy', 16)
|
|
w78.u32LE(7)
|
|
expect(decodeD2gsS2cPacket(w78.toUint8Array())).toEqual({
|
|
type: 'Trade',
|
|
action: 0x78,
|
|
partnerId: 7,
|
|
partnerName: 'TradeBuddy',
|
|
})
|
|
|
|
const w79 = new ByteWriter(6)
|
|
w79.u8(0x79)
|
|
w79.u8(1)
|
|
w79.u32LE(12500)
|
|
expect(decodeD2gsS2cPacket(w79.toUint8Array())).toEqual({
|
|
type: 'Trade',
|
|
action: 0x7901,
|
|
gold: 12500,
|
|
})
|
|
|
|
const w92 = new ByteWriter(6)
|
|
w92.u8(0x92)
|
|
w92.u8(0)
|
|
w92.u32LE(7)
|
|
expect(decodeD2gsS2cPacket(w92.toUint8Array())).toEqual({
|
|
type: 'Trade',
|
|
action: 0x9200,
|
|
partnerId: 7,
|
|
})
|
|
})
|
|
})
|