update v3, fix: Can not use ability in technique,

skip battle when using Acheron/Trashbin's technique
on normall mobs, added cosmetic gameserver log
This commit is contained in:
HuLiNap 2025-06-03 11:54:12 +07:00
parent 5f9ba04784
commit 4bd91c5a2f
10 changed files with 191 additions and 50 deletions

View file

@ -44,7 +44,7 @@ page and download the latest release for your platform.
- Test battle via calyx
- MOC/PF/AS simulator
- Gacha simulator
- Support command for Sillyism (there are some bugs right now )
- Support command for Sillyism
## Contributing

View file

@ -4,10 +4,10 @@
"name": "Saber",
"id": 1014,
"hp": 100,
"sp": 0,
"sp": 50,
"level": 80,
"promotion": 6,
"rank": 6,
"rank": 0,
"lightcone": {
"id": 23045,
"rank": 1,
@ -31,7 +31,7 @@
"sp": 50,
"level": 80,
"promotion": 6,
"rank": 6,
"rank": 0,
"lightcone": {
"id": 23042,
"rank": 1,
@ -55,7 +55,7 @@
"sp": 50,
"level": 80,
"promotion": 6,
"rank": 6,
"rank": 0,
"lightcone": {
"id": 23038,
"rank": 1,
@ -79,7 +79,7 @@
"sp": 50,
"level": 80,
"promotion": 6,
"rank": 6,
"rank": 0,
"lightcone": {
"id": 23029,
"rank": 5,
@ -167,6 +167,78 @@
"63196,15,3,4,10:3:3,8:3:3,7:2:2,6:1:1"
],
"use_technique": true
},
{
"name": "Acheron",
"id": 1308,
"hp": 100,
"sp": 50,
"level": 80,
"promotion": 6,
"rank": 6,
"lightcone": {
"id": 23024,
"rank": 5,
"level": 80,
"promotion": 6
},
"relics": [
"61261,15,1,4,7:4:4,12:3:3,4:1:1,9:1:1",
"61262,15,1,4,1:3:3,4:2:2,7:2:2,9:2:2",
"61263,15,5,4,4:1:1,6:2:2,2:3:3,8:3:3",
"61264,15,2,4,11:4:4,8:2:2,4:1:1,10:2:2",
"63145,15,7,4,9:5:5,8:2:2,1:1:1,2:1:1",
"63146,15,4,4,2:4:4,10:1:1,8:1:1,12:3:3"
],
"use_technique": true
},
{
"name": "Anaxa",
"id": 1405,
"hp": 100,
"sp": 50,
"level": 80,
"promotion": 6,
"rank": 0,
"lightcone": {
"id": 23041,
"rank": 1,
"level": 80,
"promotion": 6
},
"relics": [
"61221,15,1,4,11:1:1,5:2:2,9:3:3,10:3:3",
"61222,15,1,4,12:1:1,9:4:4,3:2:2,5:2:2",
"61223,15,5,4,11:2:2,2:2:2,1:4:4,5:1:1",
"61224,15,4,4,10:3:3,8:3:3,4:2:2,9:1:1",
"63175,15,8,4,7:2:2,9:2:2,4:1:1,8:4:4",
"63176,15,4,4,7:3:3,8:2:2,3:2:2,4:2:2"
],
"use_technique": false
},
{
"name": "Castorice",
"id": 1407,
"hp": 100,
"sp": 50,
"level": 80,
"promotion": 6,
"rank": 0,
"lightcone": {
"id": 23040,
"rank": 1,
"level": 80,
"promotion": 6
},
"relics": [
"61241,15,1,4,4:2:2,9:3:3,12:1:1,8:3:3",
"61242,15,1,4,5:2:2,1:2:2,6:3:3,8:2:2",
"61243,15,5,4,10:2:2,3:2:2,1:2:2,6:3:3",
"61244,15,1,4,3:2:2,6:2:2,2:4:4,5:1:1",
"63195,15,1,4,11:1:1,8:2:2,6:3:3,10:3:3",
"63196,15,3,4,2:2:2,8:3:3,7:1:1,3:3:3"
],
"use_technique": false
}
],
"battle_config": {

View file

@ -6,6 +6,7 @@ const Packet = @import("../Packet.zig");
const Config = @import("../services/config.zig");
const Item = @import("../services/item.zig");
const Data = @import("../data.zig");
const LineupData = @import("../manager/lineup_mgr.zig");
const ArrayList = std.ArrayList;
const Allocator = std.mem.Allocator;
@ -146,6 +147,12 @@ pub fn onSyncAvatar(session: *Session, _: []const u8, allocator: Allocator) Erro
}
try char.avatar_list.append(avatar);
const avatarType: protocol.MultiPathAvatarType = @enumFromInt(avatarConf.id);
if (avatarConf.id >= 8001 and avatarConf.id <= 8008) {
LineupData.mc_id = avatarConf.id;
}
if (avatarConf.id == 1001 or avatarConf.id == 1224) {
LineupData.m7th = avatarConf.id;
}
if (@intFromEnum(avatarType) > 1) {
try session.send(CmdID.CmdSetAvatarPathScRsp, protocol.SetAvatarPathScRsp{
.retcode = 0,

View file

@ -6,6 +6,8 @@ pub const McTracing = [_]u32{
8002, 8004, 8006, 8008,
};
pub const EnhanceAvatarID = [_]u32{ 1005, 1006, 1205, 1212 };
pub const IgnoreBattle = [_]u32{ 1405, 1404, 1225, 1314, 1312, 1305, 1302, 1217 };
pub const SkipBattle = [_]u32{ 1408, 1308 };
pub const skills = [_]u32{ 1, 2, 3, 4, 7, 101, 102, 103, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 301, 302 };
pub const skills_old = [_]u32{ 1, 2, 3, 4, 7, 101, 102, 103, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210 };

View file

@ -24,6 +24,8 @@ fn containsAny(list: []const u32, ids: []const u32) bool {
}
return false;
}
pub var mc_id: u32 = 8008;
pub var m7th: u32 = 1224;
pub const LineupManager = struct {
allocator: std.mem.Allocator,
@ -116,7 +118,10 @@ pub fn getSelectedAvatarID(allocator: std.mem.Allocator, input: []const u32) !vo
try tempList.appendSlice(input);
for (tempList.items) |*item| {
if (item.* == 8001) {
item.* = 8008;
item.* = mc_id;
}
if (item.* == 1001) {
item.* = m7th;
}
}
var i: usize = 0;

View file

@ -90,7 +90,7 @@ pub const SceneManager = struct {
.entityCase_ = .{ .NpcMonster = monster_info },
.GroupId = scene_group.group_id,
.InstId = monsConf.instId,
.EntityId = generator.nextId(),
.EntityId = if ((monsConf.monsterId / 1000) % 10 == 3) monster_info.monster_id else generator.nextId(),
.Motion = .{
.pos = .{ .x = monsConf.pos.x, .y = monsConf.pos.y, .z = monsConf.pos.z },
.rot = .{ .x = monsConf.rot.x, .y = monsConf.rot.y, .z = monsConf.rot.z },

View file

@ -4,6 +4,7 @@ const Session = @import("../Session.zig");
const Packet = @import("../Packet.zig");
const Config = @import("config.zig");
const Data = @import("../data.zig");
const LineupData = @import("../manager/lineup_mgr.zig");
const UidGenerator = @import("item.zig").UidGenerator;
const ArrayList = std.ArrayList;
@ -183,6 +184,12 @@ pub fn onGetAvatarData(session: *Session, packet: *const Packet, allocator: Allo
}
try rsp.avatar_list.append(avatar);
const avatarType: protocol.MultiPathAvatarType = @enumFromInt(avatarConf.id);
if (avatarConf.id >= 8001 and avatarConf.id <= 8008) {
LineupData.mc_id = avatarConf.id;
}
if (avatarConf.id == 1001 or avatarConf.id == 1224) {
LineupData.m7th = avatarConf.id;
}
if (@intFromEnum(avatarType) > 1) {
try session.send(CmdID.CmdSetAvatarPathScRsp, protocol.SetAvatarPathScRsp{
.retcode = 0,

View file

@ -13,6 +13,18 @@ const ArrayList = std.ArrayList;
const Allocator = std.mem.Allocator;
const CmdID = protocol.CmdID;
const log = std.log.scoped(.scene_service);
// Function to check if an ID is in a list
fn isInList(id: u32, list: []const u32) bool {
for (list) |item| {
if (item == id) {
return true;
}
}
return false;
}
pub var on_battle: bool = false;
pub fn onStartCocoonStage(session: *Session, packet: *const Packet, allocator: Allocator) !void {
@ -71,26 +83,37 @@ pub fn onSceneCastSkill(session: *Session, packet: *const Packet, allocator: All
const req = try packet.getProto(protocol.SceneCastSkillCsReq, allocator);
var battle_info: ?protocol.SceneBattleInfo = null;
var monster_battle_info_list = ArrayList(protocol.HitMonsterBattleInfo).init(allocator);
std.debug.print("SKILL INDEX: {}\n", .{req.skill_index});
Highlight("SKILL INDEX: {}", .{req.skill_index});
Highlight("ATTACKED BY ENTITY ID: {}", .{req.attacked_by_entity_id});
const is_challenge = ChallengeData.on_challenge;
for (req.assist_monster_entity_id_list.items) |id| {
std.debug.print("ASSIST ID: {}\n", .{id});
if ((req.attacked_by_entity_id >= 1 and req.attacked_by_entity_id <= 1000) or
(req.assist_monster_entity_id_list.items.len > 0 and id < 1000))
{
const list = protocol.HitMonsterBattleInfo{
.target_monster_entity_id = id,
.monster_battle_type = protocol.MonsterBattleType.MONSTER_BATTLE_TYPE_TRIGGER_BATTLE,
};
try monster_battle_info_list.append(list);
if (ChallengeData.on_challenge) {
battle_info = challenge;
} else {
battle_info = battle;
on_battle = true;
const attacker_id = req.attacked_by_entity_id;
const skill_index = req.skill_index;
const bt = getBattleType(id, attacker_id, skill_index, is_challenge);
if (is_challenge) {
if ((attacker_id <= 1000) or (id < 1000)) {
Highlight("CHALLENGE, MONSTER ENTITY ID: {} -> {}", .{ id, bt });
try monster_battle_info_list.append(.{
.target_monster_entity_id = id,
.monster_battle_type = bt,
});
if (bt == protocol.MonsterBattleType.MONSTER_BATTLE_TYPE_TRIGGER_BATTLE) {
battle_info = challenge;
}
}
} else {
if ((attacker_id <= 1000 or attacker_id > 1000000) or (id < 1000 or id > 1000000)) {
Highlight("BATTLE, MONSTER ENTITY ID: {} -> {}", .{ id, bt });
try monster_battle_info_list.append(.{
.target_monster_entity_id = id,
.monster_battle_type = bt,
});
if (bt == protocol.MonsterBattleType.MONSTER_BATTLE_TYPE_TRIGGER_BATTLE) {
battle_info = battle;
on_battle = true;
}
}
}
//TODO: DO IGNORE BATTLE AND SKIP BATTLE
}
try session.send(CmdID.CmdSceneCastSkillScRsp, protocol.SceneCastSkillScRsp{
.retcode = 0,
@ -138,3 +161,35 @@ pub fn onSyncClientResVersion(session: *Session, packet: *const Packet, allocato
.client_res_version = req.client_res_version,
});
}
fn Highlight(comptime msg: []const u8, args: anytype) void {
std.debug.print("\x1b[33m", .{});
std.debug.print(msg, args);
std.debug.print("\x1b[0m\n", .{});
}
fn getBattleType(id: u32, attacker_id: u32, skill_index: u32, is_challenge: bool) protocol.MonsterBattleType {
if (skill_index != 1) {
return protocol.MonsterBattleType.MONSTER_BATTLE_TYPE_TRIGGER_BATTLE;
}
if (attacker_id >= 1 and attacker_id <= 1000) {
return protocol.MonsterBattleType.MONSTER_BATTLE_TYPE_TRIGGER_BATTLE;
}
if (attacker_id >= 100000) {
const attacker_offset = attacker_id - 100000;
if (isInList(attacker_offset, &Data.IgnoreBattle)) {
return protocol.MonsterBattleType.MONSTER_BATTLE_TYPE_NO_BATTLE;
}
if (isInList(attacker_offset, &Data.SkipBattle)) {
if (is_challenge) {
return protocol.MonsterBattleType.MONSTER_BATTLE_TYPE_TRIGGER_BATTLE;
} else {
if (id > 1000000) {
return protocol.MonsterBattleType.MONSTER_BATTLE_TYPE_TRIGGER_BATTLE;
} else {
return protocol.MonsterBattleType.MONSTER_BATTLE_TYPE_DIRECT_DIE_SKIP_BATTLE;
}
}
}
}
return protocol.MonsterBattleType.MONSTER_BATTLE_TYPE_TRIGGER_BATTLE;
}

View file

@ -26,7 +26,7 @@ pub fn onSceneEntityMove(session: *Session, packet: *const Packet, allocator: Al
const req = try packet.getProto(protocol.SceneEntityMoveCsReq, allocator);
for (req.entity_motion_list.items) |entity_motion| {
if (entity_motion.motion) |motion| {
if (entity_motion.entity_id > 99999 or entity_motion.entity_id == 0)
if (entity_motion.entity_id > 99999 and entity_motion.entity_id < 1000000 or entity_motion.entity_id == 0)
log.debug("[POSITION] entity_id: {}, motion: {}", .{ entity_motion.entity_id, motion });
}
}
@ -232,6 +232,15 @@ pub fn onDeactivateFarmElement(session: *Session, packet: *const Packet, allocat
.entity_id = req.entity_id,
});
}
pub fn onActivateFarmElement(session: *Session, packet: *const Packet, allocator: Allocator) !void {
const req = try packet.getProto(protocol.ActivateFarmElementCsReq, allocator);
std.debug.print("ACTIVATE FARM ELEMENT ENTITY ID: {}\n", .{req.entity_id});
try session.send(CmdID.CmdActivateFarmElementScRsp, protocol.ActivateFarmElementScRsp{
.retcode = 0,
.world_level = req.world_level,
.entity_id = req.entity_id,
});
}
pub fn onSetGroupCustomSaveData(session: *Session, packet: *const Packet, allocator: Allocator) !void {
const req = try packet.getProto(protocol.SetGroupCustomSaveDataCsReq, allocator);
//switch (req.AAMHHECOCOI) {

View file

@ -1,28 +1,4 @@
{
"OSBETAWin3.2.51": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_9961450_404865fc6856_fbf8b526e6b08c",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_9984498_2b39fa0086e4_1f081bc40d1782",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_0_40d2ce0253",
"ifix_version": "0",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_9961575_227d4559d8e3_cd27ed7ca2bbfd",
"lua_version": ""
},
"OSBETAWin3.2.52": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_10025177_f10d2880371c_719811bc00424c",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_10037027_be14d3e01696_5aa1cd3547cbdb",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_0_40d2ce0253_6d871f8bca6eb4",
"ifix_version": "0",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_10025298_1dc728a6c8ee_1128f068b506d4",
"lua_version": ""
},
"OSBETAWin3.2.53": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_10104345_a5535dc0c779_a36b870100988f",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_10128229_1abd7f8c3047_3cb3e1bffdb636",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_0_40d2ce0253_6d871f8bca6eb4",
"ifix_version": "0",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_10104505_31a450a7e7a3_0793e9a5426e39",
"lua_version": ""
},
"CNBETAWin3.3.51": {
"asset_bundle_url": "https://autopatchcn.bhsr.com/asb/BetaLive/output_10451237_a3aa836fce75_f560b891c0d21e",
"ex_resource_url": "https://autopatchcn.bhsr.com/design_data/BetaLive/output_10459782_ced8509d61c9_cdbde1049f2207",
@ -38,5 +14,13 @@
"ifix_version": "0",
"lua_url": "https://autopatchcn.bhsr.com/lua/BetaLive/output_10506685_892409531f16_67592aefeb2f2b",
"lua_version": ""
},
"CNBETAWin3.3.53": {
"asset_bundle_url": "https://autopatchcn.bhsr.com/asb/BetaLive/output_10553897_658616122c5e_1311a7ab7701f7",
"ex_resource_url": "https://autopatchcn.bhsr.com/design_data/BetaLive/output_10564145_db8507c78423_dc92dd047d442d",
"ifix_url": "https://autopatchcn.bhsr.com/ifix/BetaLive/output_0_40d2ce0253_c61ba99f70b885",
"ifix_version": "0",
"lua_url": "https://autopatchcn.bhsr.com/lua/BetaLive/output_10554126_56a3036b1f8c_6dab2038cb17c3",
"lua_version": ""
}
}