214 lines
6.8 KiB
C#
214 lines
6.8 KiB
C#
using PSO2SERVER.Database;
|
|
using PSO2SERVER.Models;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Runtime.Remoting.Contexts;
|
|
using System.Text;
|
|
using static PSO2SERVER.Models.CharacterStruct;
|
|
|
|
namespace PSO2SERVER.Protocol.Packets
|
|
{
|
|
public class CharacterListPacket : Packet
|
|
{
|
|
public uint Characters_count { get; set; } = 0;
|
|
public uint unk1 { get; set; } = 0;
|
|
// Available characters
|
|
public List<Character> Characters { get; set; } = new List<Character>();
|
|
|
|
// Equipped items (List of 10 Items for each character)
|
|
public List<PSO2Items[]> EquippedItems { get; set; } = new List<PSO2Items[]>();
|
|
|
|
// Character play times (30 times)
|
|
public List<uint> PlayTimes { get; set; } = new List<uint>();
|
|
|
|
// Character deletion flags (flag, deletion timestamp) (30 pairs of (u32, u32))
|
|
public List<(uint flag, uint timestamp)> DeletionFlags { get; set; } = new List<(uint, uint)>();
|
|
|
|
// Character ship transfer flags (30 pairs of (u32, u32))
|
|
public List<(uint flag, uint timestamp)> TransferFlags { get; set; } = new List<(uint, uint)>();
|
|
|
|
// Account accessory flag (unknown)
|
|
public ushort AccountAccessory { get; set; }
|
|
|
|
// Login survey flag
|
|
public uint LoginSurvey { get; set; }
|
|
|
|
// Ad flag
|
|
public uint Ad { get; set; }
|
|
|
|
// Ninji note: This packet may be followed by extra data,
|
|
// after a fixed-length array of character data structures.
|
|
// Needs more investigation at some point.
|
|
// ---
|
|
// CK note: Extra data is likely current equipment, playtime, etc.
|
|
// All of that data is currently unaccounted for at the moment.
|
|
//忍者注意:这个包后面可能有额外的数据,
|
|
//在固定长度的字符数据结构数组之后。
|
|
//需要更多的调查。
|
|
// ---
|
|
// CK注:额外的数据可能是当前设备,游戏时间等。
|
|
//所有这些数据目前都是未知的。
|
|
|
|
private int AccountId;
|
|
|
|
public CharacterListPacket(int AccountId)
|
|
{
|
|
Characters = new List<Character>();
|
|
EquippedItems = new List<PSO2Items[]>();
|
|
PlayTimes = new List<uint>();
|
|
DeletionFlags = new List<(uint, uint)>();
|
|
TransferFlags = new List<(uint, uint)>();
|
|
AccountAccessory = 0;
|
|
LoginSurvey = 0;
|
|
Ad = 0;
|
|
this.AccountId = AccountId;
|
|
}
|
|
|
|
#region implemented abstract members of Packet
|
|
|
|
public override byte[] Build()
|
|
{
|
|
using (var db = new ServerEf())
|
|
{
|
|
var chars = db.Characters
|
|
.Where(w => w.AccountID == AccountId)
|
|
.OrderBy(o => o.CharacterID) // TODO: 按照最后游玩的角色排序
|
|
.Select(s => s);
|
|
|
|
foreach (var ch in chars)
|
|
{
|
|
Characters.Add(ch);
|
|
|
|
//PSO2Items[] items = new PSO2Items[10];
|
|
|
|
//for (var i = 0; i < 10; i++)
|
|
//{
|
|
// items[i] = new PSO2Items
|
|
// {
|
|
// uuid = (ulong)i,
|
|
// id = new ItemId
|
|
// {
|
|
// ItemType = 3,
|
|
// Id = 1,
|
|
// Subid = 0,
|
|
// },
|
|
// data = new Items
|
|
// {
|
|
// Consumable = new PSO2ItemConsumable
|
|
// {
|
|
// flags = 0,
|
|
// amount = 10,
|
|
// },
|
|
// }
|
|
// };
|
|
//}
|
|
|
|
//ch.EquipedItems = items;
|
|
|
|
//EquippedItems.Add(ch.EquipedItems);
|
|
|
|
//ch.Playe_time = 0xFFFFFFFF;
|
|
|
|
//PlayTimes.Add(ch.Playe_time);
|
|
|
|
//var deletionFlags = (0, 0);
|
|
|
|
//DeletionFlags.Add(((uint flag, uint timestamp))deletionFlags);
|
|
|
|
//var transferFlags = (0, 0);
|
|
|
|
//TransferFlags.Add(((uint flag, uint timestamp))transferFlags);
|
|
|
|
}
|
|
|
|
Characters_count = (uint)Characters.Count();
|
|
}
|
|
|
|
var rest_count = 30 - Characters_count;
|
|
|
|
for (var i = 0; i < rest_count; i++)
|
|
{
|
|
Characters.Add(Characters[0]);
|
|
|
|
//EquippedItems.Add(EquippedItems[0]);
|
|
|
|
//PlayTimes.Add(0x12345678);
|
|
|
|
//var deletionFlags = (1, 3);
|
|
|
|
//DeletionFlags.Add(((uint flag, uint timestamp))deletionFlags);
|
|
|
|
//var transferFlags = (2, 4);
|
|
|
|
//TransferFlags.Add(((uint flag, uint timestamp))transferFlags);
|
|
}
|
|
|
|
var pkt = new PacketWriter();
|
|
|
|
pkt.Write(Characters_count); // 写入玩家数量
|
|
pkt.Write(unk1);
|
|
foreach (var ch in Characters)
|
|
{
|
|
pkt.Write((uint)0);
|
|
pkt.Write(ch.BuildCharacterByteArray());//4
|
|
}
|
|
|
|
pkt.Write(File.ReadAllBytes("packets/charlist_rest.bin"));
|
|
//pkt.Write((uint)EquippedItems.Count()); // 写入物品数量
|
|
//foreach (var itemsArray in EquippedItems)
|
|
//{
|
|
// foreach (var item in itemsArray)
|
|
// {
|
|
// pkt.Write(item.ToByteArray());
|
|
// }
|
|
//}
|
|
//// Write PlayTimes
|
|
//foreach (var playTime in PlayTimes)
|
|
//{
|
|
// pkt.Write(playTime);
|
|
//}
|
|
|
|
//pkt.WriteBytes(0, 32);
|
|
|
|
//// Write DeletionFlags
|
|
//foreach (var flag in DeletionFlags)
|
|
//{
|
|
// pkt.Write(flag.flag);
|
|
// pkt.Write(flag.timestamp);
|
|
//}
|
|
//// Write TransferFlags
|
|
//foreach (var flag in TransferFlags)
|
|
//{
|
|
// pkt.Write(flag.flag);
|
|
// pkt.Write(flag.timestamp);
|
|
//}
|
|
|
|
//// Write AccountAccessory
|
|
//pkt.Write(AccountAccessory);
|
|
|
|
//pkt.WriteBytes(0, 6);
|
|
|
|
//// Write LoginSurvey
|
|
//pkt.Write(LoginSurvey);
|
|
|
|
//// Write Ad
|
|
//pkt.Write(Ad);
|
|
|
|
//pkt.WriteBytes(0, 4);
|
|
|
|
//pkt.WriteBytes(0, 4);
|
|
|
|
return pkt.ToArray();
|
|
}
|
|
|
|
public override PacketHeader GetHeader()
|
|
{
|
|
return new PacketHeader(0x11, 0x03, PacketFlags.None);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |