Files
90CNServer/server/internal/services/dnfbridge/userinfo_legacy_build_02c1_03cd.go
hanfuit 645b64fe21 DNF90 服务端与启动器完整源码(含 GM 工具功能增强)
服务端(Go):
- GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面
- GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新
- 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新)
- 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍
- 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0)
- 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算

启动器(Python/JS):
- 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭
- GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐)
- 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
2026-11-04 14:31:55 +08:00

269 lines
8.2 KiB
Go

package dnfbridge
import (
dnfrepo "longheng.io/server/internal/modules/dnf/repository"
"strings"
)
func (r *csharpLegacyUserInfoReader) build2C1() []byte {
row, ok := r.rawOne("legacy_character_userinfo2c1_state", []string{"value_a", "value_b"})
if !ok {
return nil
}
var w packetWriter
w.writeUint32(rowU32(row, "value_a", 0))
w.writeUint32(rowU32(row, "value_b", 0))
r.loaded = true
return w.bytes()
}
func (r *csharpLegacyUserInfoReader) build2D2() []byte {
state, ok := r.rawOne("legacy_character_userinfo2d2_state", []string{"flag", "value_a", "value_b", "value_c"})
if !ok {
return nil
}
groups := r.queryRows("legacy_character_userinfo2d2_groups",
[]string{"sort_order", "group_key", "word_a", "word_b"},
[]string{"sort_order"},
false)
rows := r.queryRows("legacy_character_userinfo2d2_rows",
[]string{"group_sort_order", "sort_order", "word", "value_a", "value_b"},
[]string{"group_sort_order", "sort_order"},
false)
pairs := r.queryRows("legacy_character_userinfo2d2_pairs",
[]string{"group_sort_order", "row_sort_order", "pair_kind", "sort_order", "word", "flag"},
[]string{"group_sort_order", "row_sort_order", "pair_kind", "sort_order"},
false)
rowsByGroup := legacyRowsByKey(rows, "group_sort_order")
pairsByRow := legacyRowsByKey(pairs, "group_sort_order", "row_sort_order")
var w packetWriter
w.writeByte(rowU8(state, "flag", 0))
w.writeUint32(rowU32(state, "value_a", 0))
w.writeUint32(rowU32(state, "value_b", 0))
w.writeUint32(rowU32(state, "value_c", 0))
w.writeUint32(uint32(len(groups)))
for _, group := range groups {
groupSort := rowInt(group, "sort_order", 0)
groupRows := rowsByGroup[legacyGroupKey(groupSort)]
w.writeUint32(rowU32(group, "group_key", 0))
w.writeUint16(rowU16(group, "word_a", 0))
w.writeUint16(rowU16(group, "word_b", 0))
w.writeUint32(uint32(len(groupRows)))
for _, row := range groupRows {
rowSort := rowInt(row, "sort_order", 0)
rowPairs := pairsByRow[legacyGroupKey(groupSort, rowSort)]
w.writeUint16(rowU16(row, "word", 0))
w.writeUint32(rowU32(row, "value_a", 0))
w.writeUint32(rowU32(row, "value_b", 0))
write2D2Pairs(&w, rowPairs, "first")
write2D2Pairs(&w, rowPairs, "second")
}
}
r.loaded = true
return w.bytes()
}
func write2D2Pairs(w *packetWriter, rows []dnfrepo.LegacyUserInfoRow, kind string) {
filtered := make([]dnfrepo.LegacyUserInfoRow, 0, len(rows))
for _, row := range rows {
if strings.EqualFold(rowString(row, "pair_kind", ""), kind) {
filtered = append(filtered, row)
}
}
filtered = limitLegacyRowsU16(filtered)
w.writeUint16(uint16(len(filtered)))
for _, row := range filtered {
w.writeUint16(rowU16(row, "word", 0))
w.writeByte(rowU8(row, "flag", 0))
}
}
func (r *csharpLegacyUserInfoReader) build324() []byte {
row, ok := r.rawOne("legacy_character_userinfo324_state", []string{"byte_a", "text", "byte_b", "byte_c"})
if !ok {
return nil
}
var w packetWriter
w.writeByte(rowU8(row, "byte_a", 0))
writeWideNullTerminatedStringMax(&w, rowString(row, "text", ""), 50)
w.writeByte(rowU8(row, "byte_b", 0))
w.writeByte(rowU8(row, "byte_c", 0))
r.loaded = true
return w.bytes()
}
func (r *csharpLegacyUserInfoReader) build336() []byte {
if _, ok := r.rawOne("legacy_character_userinfo336_state", []string{"note"}); !ok {
return nil
}
rows := limitLegacyRowsU8(r.queryRows("legacy_character_userinfo336_rows",
[]string{"sort_order", "byte_a", "text", "byte_b", "byte_c", "packed_flag", "byte_d"},
[]string{"sort_order"},
false))
var w packetWriter
w.writeByte(byte(len(rows)))
for _, row := range rows {
w.writeByte(rowU8(row, "byte_a", 0))
writeWideNullTerminatedStringMax(&w, rowString(row, "text", ""), 30)
w.writeByte(rowU8(row, "byte_b", 0))
w.writeByte(rowU8(row, "byte_c", 0))
w.writeByte(rowU8(row, "packed_flag", 0))
w.writeByte(rowU8(row, "byte_d", 0))
}
r.loaded = true
return w.bytes()
}
func (r *csharpLegacyUserInfoReader) build34CText() []byte {
row, ok := r.rawOne("legacy_character_userinfo34c_text_state", []string{"category", "text"})
if !ok {
return nil
}
var w packetWriter
w.writeByte(rowU8(row, "category", 0))
writeWideNullTerminatedStringMax(&w, rowString(row, "text", ""), 64)
r.loaded = true
return w.bytes()
}
func (r *csharpLegacyUserInfoReader) build34DValue() []byte {
return r.buildOneU32IfPresent("legacy_character_userinfo34d_value_state", "value")
}
func (r *csharpLegacyUserInfoReader) build34EByte() []byte {
return r.buildOneU8IfPresent("legacy_character_userinfo34e_byte_state", "value")
}
func (r *csharpLegacyUserInfoReader) build352() []byte {
row, ok := r.rawOne("legacy_character_userinfo352_state", []string{"value_a", "value_b"})
if !ok {
return nil
}
var w packetWriter
w.writeUint32(rowU32(row, "value_a", 0))
w.writeUint32(rowU32(row, "value_b", 0))
r.loaded = true
return w.bytes()
}
func (r *csharpLegacyUserInfoReader) build354() []byte {
row, ok := r.rawOne("legacy_character_userinfo354_state", []string{"word0", "word1", "word2", "word3", "word4"})
if !ok {
return nil
}
var w packetWriter
w.writeUint16(rowU16(row, "word0", 0))
w.writeUint16(rowU16(row, "word1", 0))
w.writeUint16(rowU16(row, "word2", 0))
w.writeUint16(rowU16(row, "word3", 0))
w.writeUint16(rowU16(row, "word4", 0))
r.loaded = true
return w.bytes()
}
func (r *csharpLegacyUserInfoReader) build359() []byte {
state, ok := r.rawOne("legacy_character_userinfo359_state", []string{"byte_a", "byte_b"})
if !ok {
return nil
}
groups := r.queryRows("legacy_character_userinfo359_groups",
[]string{"sort_order", "group_key", "raw0", "raw1", "raw2"},
[]string{"sort_order"},
false)
var w packetWriter
w.writeByte(rowU8(state, "byte_a", 0))
w.writeByte(rowU8(state, "byte_b", 0))
w.writeUint32(uint32(len(groups)))
for _, group := range groups {
raw0 := rowBytes(group, "raw0")
raw1 := rowBytes(group, "raw1")
raw2 := rowBytes(group, "raw2")
if !legacyPayloadLengthOK(raw0, 52) || !legacyPayloadLengthOK(raw1, 52) || !legacyPayloadLengthOK(raw2, 52) {
return nil
}
w.writeUint32(rowU32(group, "group_key", 0))
w.writeBytes(raw0)
w.writeBytes(raw1)
w.writeBytes(raw2)
}
r.loaded = true
return w.bytes()
}
func (r *csharpLegacyUserInfoReader) build36B() []byte {
if _, ok := r.rawOne("legacy_character_userinfo36b_state", []string{"note"}); !ok {
return nil
}
rows := limitLegacyRowsU8(r.queryRows("legacy_character_userinfo36b_rows",
[]string{"sort_order", "kind", "byte_a", "byte_b", "byte_c", "word_a", "value", "byte_d", "word_b"},
[]string{"sort_order"},
false))
var w packetWriter
w.writeByte(byte(len(rows)))
for _, row := range rows {
kind := rowU8(row, "kind", 0)
w.writeByte(kind)
w.writeByte(rowU8(row, "byte_a", 0))
if kind == 0 {
w.writeByte(rowU8(row, "byte_b", 0))
w.writeByte(rowU8(row, "byte_c", 0))
continue
}
w.writeUint16(rowU16(row, "word_a", 0))
w.writeUint32(rowU32(row, "value", 0))
w.writeByte(rowU8(row, "byte_d", 0))
w.writeUint16(rowU16(row, "word_b", 0))
}
r.loaded = true
return w.bytes()
}
func (r *csharpLegacyUserInfoReader) build37B() []byte {
row, ok := r.rawOne("legacy_character_userinfo37b_state", []string{"value", "raw124", "raw64"})
if !ok {
return nil
}
raw124 := rowBytes(row, "raw124")
raw64 := rowBytes(row, "raw64")
if !legacyPayloadLengthOK(raw124, 124) || !legacyPayloadLengthOK(raw64, 64) {
return nil
}
var w packetWriter
w.writeUint32(rowU32(row, "value", 0))
w.writeBytes(raw124)
w.writeBytes(raw64)
r.loaded = true
return w.bytes()
}
func (r *csharpLegacyUserInfoReader) build393() []byte {
if _, ok := r.rawOne("legacy_character_userinfo393_state", []string{"note"}); !ok {
return nil
}
rows := limitLegacyRowsU8(r.queryRows("legacy_character_userinfo393_rows",
[]string{"sort_order", "value_a", "value_b"},
[]string{"sort_order"},
false))
var w packetWriter
w.writeByte(byte(len(rows)))
for _, row := range rows {
w.writeUint32(rowU32(row, "value_a", 0))
w.writeUint32(rowU32(row, "value_b", 0))
}
r.loaded = true
return w.bytes()
}
func (r *csharpLegacyUserInfoReader) build3CD() []byte {
row, ok := r.rawOne("legacy_character_userinfo3cd_state", []string{"flag", "value"})
if !ok {
return nil
}
var w packetWriter
w.writeByte(rowU8(row, "flag", 0))
w.writeUint32(rowU32(row, "value", 0))
r.loaded = true
return w.bytes()
}