PSO2SERVER/Server/Protocol/Packets/11-ClientPacket/11-03-CharacterListPacket.cs

176 lines
5.7 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 uint[] PlayTimes { get; set; } = new uint[30];
// Character deletion flags (flag, deletion timestamp) (30 pairs of (u32, u32))
public (uint flag, uint timestamp)[] DeletionFlags { get; set; } = new (uint, uint)[30];
// Character ship transfer flags (30 pairs of (u32, u32))
public (uint flag, uint timestamp)[] TransferFlags { get; set; } = new (uint, uint)[30];
// 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)
{
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);
//// 创建一个 Consumable 类型的物品
//PSO2ItemConsumable consumableItem = new PSO2ItemConsumable
//{
// amount = 10,
//};
//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 = consumableItem }
// };
//}
ch.EquipedItems = new PSO2Items[10];
EquippedItems.Add(ch.EquipedItems);
}
Characters_count = (uint)Characters.Count();
}
var rest_count = 30 - Characters_count;
for (var i = 0; i < rest_count; i++)
{
//Character character = Characters[0];
Characters.Add(Characters[0]);
EquippedItems.Add(EquippedItems[0]);
}
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.WriteStruct(item);
// }
//}
//// Write PlayTimes
//foreach (var playTime in PlayTimes)
//{
// pkt.Write(playTime);
//}
//// 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);
//// Write LoginSurvey
//pkt.Write(LoginSurvey);
//// Write Ad
//pkt.Write(Ad);
//pkt.WriteBytes(0, 2);
return pkt.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x11, 0x03, PacketFlags.None);
}
#endregion
}
}