Mip
Donkey Kong
- 25/9/04
- 309
- 0
Nghĩ lại ngày xưa, nhiều người hợp tác, đầu tư làm server ts, lên con số vài tỉ, nhưng cuộc sống bản thân tôi còn không ổn, làm sao theo nổi những dự án tầm cỡ vĩ đại như trên.
Bây giờ bình tâm lại, giữ lại kiến thức cũng không giúp được gì, vì thời gian không cho phép ngồi code và quản trị cái hệ thống đó, nên giờ chia sẽ kiến thức với mọi người.
Vì vậy, nên hôm nay tôi mở chuyên mục tư vấn về hệ thống TSOnline, mọi người có thể đặt bất cứ câu hỏi gì về server TS, ví dụ muốn làm server cần điều kiện gì, giải mã data thế nào, các dự án TS hiện giờ thế nào...
Còn về các bí mật sâu hơn về hệ thống, như hệ thống warp, talk, Quest... vận hành thế nào, tôi sẽ trả lời về nó, chỉ cần bạn chứng minh 1 điều, và cam kết 1 điều.
- Điều phải chứng minh: Cho tôi thấy được bạn đã giải quyết packet Nhật ký Quest.
- Điều phải cam kết: Mở 1 server TS phi lợi nhuận để mọi người cùng tham gia, chi phí tính vào chi phí donate. Còn bạn muốn mở server ts để kiếm tiền thì xin lỗi, tôi không giúp bạn được.
Talk.Dat
Warp.Dat
Skill.Dat
24/9/2013: Có bạn hỏi tôi, muốn làm server game cần những gì, đây tôi nêu 1 số kiến thức trong khả năng có hạn của tôi.
1. Kiến thức lập trình căn bản, và ngôn ngữ lập trình chỉ cần hỗ trợ lập trình socket.
2. Có chút kiến thức về packet. Vì việc đầu tiên không phải là phân tích packet đó làm gì, muh là packet đó có cấu trúc như thế nào.
3. Có chút kinh nghiệm về mã hóa. Như chụp packet khi đăng nhập, xem nó packet có giống nhau sau 2 lần chụp hay không...
4. Có chút kinh nghiệm về research. Thời buổi này bác Gu Gồ bự lắm, kiếm gì cũng có, quan trọng là phải biết kiếm đúng chỗ.
5. Kiếm chút tài liệu về asm để đọc, có thể đọc để debug ở mức căn bản, còn không làm được, thì ráng kiếm làm sao có Data của của game do các cao thủ nào leak ra, rồi sử dụng nó làm data căn bản.
6. Biết điểm dừng lại. Vì 1 người không thể làm hoàn chỉnh 1 server được đâu, nếu muôn học hỏi thì nên đưa target tầm ngắn thôi. Và đơn giản nhất là làm mấy cái BOT trước, vì BOT nó đơn giản hơn server game nhiều.
7. Nắm vững cấu trúc dữ liệu, vì "int A = 4;" khác với "byte A = 4".
.....
Còn nhiều, rất nhiều cái để nói, vài dòng trên đây không thể nói hết. Nếu anh em muốn gặp nhau chia sẽ kinh nghiệm ở TPHCM thì lúc nào cũng hoan nghênh. Vì kiến thức không thể phát triển nếu không chia sẽ.
Bây giờ bình tâm lại, giữ lại kiến thức cũng không giúp được gì, vì thời gian không cho phép ngồi code và quản trị cái hệ thống đó, nên giờ chia sẽ kiến thức với mọi người.
Vì vậy, nên hôm nay tôi mở chuyên mục tư vấn về hệ thống TSOnline, mọi người có thể đặt bất cứ câu hỏi gì về server TS, ví dụ muốn làm server cần điều kiện gì, giải mã data thế nào, các dự án TS hiện giờ thế nào...
Còn về các bí mật sâu hơn về hệ thống, như hệ thống warp, talk, Quest... vận hành thế nào, tôi sẽ trả lời về nó, chỉ cần bạn chứng minh 1 điều, và cam kết 1 điều.
- Điều phải chứng minh: Cho tôi thấy được bạn đã giải quyết packet Nhật ký Quest.
- Điều phải cam kết: Mở 1 server TS phi lợi nhuận để mọi người cùng tham gia, chi phí tính vào chi phí donate. Còn bạn muốn mở server ts để kiếm tiền thì xin lỗi, tôi không giúp bạn được.
Talk.Dat
PHP:
{
FileName = "Talk.Dat";
iBlock = 257;
var buffer = getBuffer(); //Kiểm tra đường dẫn và đọc hết toàn bộ byte từ file (ReadAllBytes)
if (buffer != null)
{
var sheet = CreateSheet(p, "Talk");
int iTotalBlock = buffer.Length / iBlock;
listData = new List<TsOnline.Entity.TalkEntity>();
sheet.Cells[1, 1].Value = "TalkID";
sheet.Cells[1, 2].Value = "Content";
for (int i = 1; i < iTotalBlock; i++)
{
TsOnline.Entity.TalkEntity item = new TsOnline.Entity.TalkEntity();
int index = i * iBlock;
sheet.Cells[i + 1, 1].Value = item.TalkID = ProgressUshort(BitConverter.ToUInt16(buffer, index));
index += 2;
item.LengthContent = buffer[index++];
Array.Reverse(buffer, index, 254);
sheet.Cells[i + 1, 2].Value = item.Content = Encoding.Default.GetString(buffer, index, item.LengthContent).Trim();
listData.Add(item);
raiseSendMessage(string.Format("Talk.Dat: {0}/{1}", i, iTotalBlock - 1));
raiseProgress(i * 100 / iTotalBlock);
}
}
}
private ushort ProgressUshort(ushort input)
{
return (ushort)((input ^ 0xECEA) - 5);
}
Warp.Dat
PHP:
{
FileName = "Warp.Dat";
iBlock = 23;
var buffer = getBuffer();
if (buffer != null)
{
var sheet = CreateSheet(p, "Warp");
int iTotalBlock = buffer.Length / iBlock;
listData = new List<TsOnline.Entity.WarpEntity>();
sheet.Cells[1, 1].Value = "Name";
sheet.Cells[1, 2].Value = "b1";
sheet.Cells[1, 3].Value = "b2";
sheet.Cells[1, 4].Value = "u1";
sheet.Cells[1, 5].Value = "i1";
sheet.Cells[1, 6].Value = "i2";
for (int i = 1; i < iTotalBlock; i++)
{
TsOnline.Entity.WarpEntity item = new TsOnline.Entity.WarpEntity();
int index = i * iBlock;
item.LengthName = buffer[index++];
Array.Reverse(buffer, index, 10);
sheet.Cells[i + 1, 1].Value = item.Name = Encoding.Default.GetString(buffer, index, item.LengthName).Trim();
index += 10;
sheet.Cells[i + 1, 2].Value = item.b1 = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 3].Value = item.b2 = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 4].Value = item.u1 = ProgressUshort(BitConverter.ToUInt16(buffer, index));
index += 2;
sheet.Cells[i + 1, 5].Value = item.i1 = ProgressInt(BitConverter.ToInt32(buffer, index));
index += 4;
sheet.Cells[i + 1, 6].Value = item.i2 = ProgressInt(BitConverter.ToInt32(buffer, index));
index += 4;
listData.Add(item);
raiseSendMessage(string.Format("Warp.Dat: {0}/{1}", i, iTotalBlock - 1));
raiseProgress(i * 100 / iTotalBlock);
}
}
}
private byte ProgressByte(byte input)
{
return (byte)((input ^ 0xC8) - 1);
}
private ushort ProgressUshort(ushort input)
{
return (ushort)((input ^ 0x5209) - 1);
}
private int ProgressInt(int input)
{
return (int)((input ^ 0x0BAEB716) - 1);
}
Skill.Dat
PHP:
public enum EnumSkillCategory : byte
{
ĐánhThường = 0,
Địa = 1,
Thủy = 2,
Hỏa = 3,
Phong = 4,
Tâm = 5,
LướiBắt = 6,
TiễnLâu = 7,
PhòngNgự = 8,
ChạyTrốn = 9,
VậtPhẩm = 10,
HấpHuyết = 11,
PhúcThầnAiThần = 12,
GiảiHộChủ = 13,
BùaChú = 14,
CựĐạiQuái = 15,
ĐặcKỹVõTướng = 16,
}
public enum EnumElement:byte
{
Không=0,
Địa=1,
Thủy=2,
Hỏa=3,
Phong=4,
Tâm=5,
TuỳNhânVậtSửDụng=6
}
public enum EnumSkillStatus:byte
{
BìnhThường=0,
PhongẤnBăngPhong=1,
PhongẤnToànPhong=2,
PhongẤnThụTinh=3,
PhongẤn=4,
PhongẤnVựngKích=5,
PhongẤnHônThụy=6,
PhongẤnChấpThiếp=7,
PhongẤn1,
PhongẤn2,
PhongẤn3,
PhongẤn4,
PhongẤn5,
PhongẤn6,
PhongẤn7,
PhongẤn8,
PhongẤn9,
PhongẤn10,
PhongẤn11,
PhongẤn12,
PhongẤn13,
PhongẤn14,
PhongẤn15,
PhongẤn16,
PhongẤn17,
PhongẤn18,
PhongẤn19,
PhongẤn20,
PhongẤn21,
PhongẤn22,
PhongẤn23,
PhongẤn24,
PhongẤn25,
PhongẤn26,
PhongẤn27,
PhongẤn28,
PhongẤn29,
PhongẤn30,
PhongẤn31,
PhongẤn32,
PhongẤn33,
PhongẤn34,
PhongẤn35,
PhongẤn36,
PhongẤn37,
PhongẤn38,
PhongẤn39,
PhongẤn40,
PhongẤn41,
PhongẤn42,
PhongẤn43=50,
CườngHóaPhongChiChiếnÝ=51,
CườngHóaCuồngNhiệtChiếnHồn=52,
CườngHóaMinhKínhChiThủy=53,
CườngHóa1,
CườngHóa2,
CườngHóa3,
CườngHóa4,
CườngHóa5,
CườngHóa6,
CườngHóa7,
CườngHóa8,
CườngHóa9,
CườngHóa10,
CườngHóa11,
CườngHóa12,
CườngHóa13,
CườngHóa14,
CườngHóa15,
CườngHóa16,
CườngHóa17,
CườngHóa18,
CườngHóa19,
CườngHóa20,
CườngHóa21,
CườngHóa22,
CườngHóa23,
CườngHóa24,
CườngHóa25,
CườngHóa26,
CườngHóa27,
CườngHóa28,
CườngHóa29,
CườngHóa30,
CườngHóa31,
CườngHóa32,
CườngHóa33,
CườngHóa34,
CườngHóa35,
CườngHóa36,
CườngHóa37,
CườngHóa38,
CườngHóa39,
CườngHóa40,
CườngHóa41,
CườngHóa42,
CườngHóa43,
CườngHóa44,
CườngHóa45,
CườngHóa46,
CườngHóa47,
BiếnHóaKếtGiới=101,
BiếnHóaLẫnTránh=102,
BiếnHóaKính=103,
BiếnHóaTườngBăng=104,
BiếnHóaẨnThân=105,
BiếnHóaNguyênKhí=106,
BiếnHóaPhóngĐại=107,
BiếnHóaĐồngTâm=108,
BiếnHóaCổVũ=109,
BiếnHóaLinhKính=110,
BiếnHóaĐơnDươngHộThể=111,
BiếnHóaĐẩuChuyểnTinhDi=112,
BiếnHóaVôHìnhVôTướng=113,
BiếnHóa1,
BiếnHóa2,
BiếnHóa3,
BiếnHóa4,
BiếnHóa5,
BiếnHóa6,
BiếnHóa7,
BiếnHóa8,
BiếnHóa9,
BiếnHóa10,
BiếnHóa11,
BiếnHóa12,
BiếnHóa13,
BiếnHóa14,
BiếnHóa15,
BiếnHóa16,
BiếnHóa17,
BiếnHóa18,
BiếnHóa19,
BiếnHóa20,
BiếnHóa21,
BiếnHóa22,
BiếnHóa23,
BiếnHóa24,
BiếnHóa25,
BiếnHóa26,
BiếnHóa27,
BiếnHóa28,
BiếnHóa29,
BiếnHóa30,
BiếnHóa31,
BiếnHóa32,
BiếnHóa33,
BiếnHóa34,
BiếnHóa35,
BiếnHóa36,
BiếnHóa37,
BiếnHóa38,
BiếnHóa39,
BiếnHóa40,
BiếnHóa41,
BiếnHóa42,
BiếnHóa43,
BiếnHóa44,
BiếnHóa45,
BiếnHóa46,
BiếnHóa47,
BiếnHóa48,
BiếnHóa49,
BiếnHóa50,
BiếnHóa51,
BiếnHóa52,
BiếnHóa53,
BiếnHóa54,
BiếnHóa55,
BiếnHóa56,
PhúcThần=170,
SuyNhượcTrúngĐộc=171,
SuyNhượcThuNhỏ=172,
SuyNhượcHỗnLoạn=173,
SuyNhượcOaLýPhản174,
SuyNhượcChậm=175,
SuyNhượcMiss=176,
SuyNhượcThổBăng=177,
SuyNhượcMãnhĐộc=178,
SuyNhượcChúcDung=179,
SuyNhượcThứcQuỷHấpHồn=180,
SuyNhượcHắcĐồNhamVươngSát=181,
SuyNhược1,
SuyNhược2,
SuyNhược3,
SuyNhược4,
SuyNhược5,
SuyNhược6,
SuyNhược7,
SuyNhược8,
SuyNhược9,
SuyNhược10,
SuyNhược11,
SuyNhược12,
SuyNhược13,
SuyNhược14,
SuyNhược15,
SuyNhược16,
SuyNhược17,
SuyNhược18,
SuyNhược19,
SuyNhược20,
SuyNhược21,
SuyNhược22,
SuyNhược23,
SuyNhược24,
SuyNhược25,
SuyNhược26,
SuyNhược27,
SuyNhược28,
SuyNhược29,
SuyNhược30,
SuyNhược31,
SuyNhược32,
SuyNhược33,
SuyNhược34,
SuyNhược35,
SuyNhược36,
SuyNhược37,
SuyNhược38,
SuyNhược39,
SuyNhược40,
SuyNhược41,
SuyNhược42,
SuyNhược43,
SuyNhược44,
SuyNhược45,
SuyNhược46,
SuyNhược47,
SuyNhược48,
SuyNhược49,
SuyNhược50,
SuyNhược51,
SuyNhược52,
SuyNhược53,
SuyNhược54,
SuyNhược55,
SuyNhược56,
SuyNhược57,
SuyNhược58,
AiThần=240,
HộChủ=241,
Max=245
}
public enum EnumSkillTypeStatus:byte
{
BìnhThường = 0,
KỹNăngHợpKích = 1,
KỹNăngPhiHợpKích = 2,
PhongẤn = 3,
BiếnHóa = 4,
HồiPhục_LoạiTrừBạn = 5,
HồiMaLực = 6,
TrịLiệu = 7,
PhụcHoạt = 8,
PhânThân = 9,
PhòngNgự = 10,
BắtGiữ = 11,
ChạyTrốn = 12,
SửDụngVậtPhẩm = 13,
SongBổ = 14,
SuyNhược = 15,
LoạiTrừKẻThù = 16,
ĐặcThù = 17,
TrịLiệuHồiPhục = 18,
CườngHóa = 19,
}
{
FileName = "Skill.Dat";
iBlock = 86;
var buffer = getBuffer();
if (buffer != null)
{
var sheet = CreateSheet(p, "Skill");
int iTotalBlock = buffer.Length / iBlock;
listData = new List<TsOnline.Entity.SkillEntity>();
sheet.Cells[1, 1].Value = "SkillName";
sheet.Cells[1, 2].Value = "iCategorySkill";
sheet.Cells[1, 3].Value = "SkillID";
sheet.Cells[1, 4].Value = "SP";
sheet.Cells[1, 5].Value = "iElement";
sheet.Cells[1, 6].Value = "NumberElement";
sheet.Cells[1, 7].Value = "ValueElement";
sheet.Cells[1, 8].Value = "Level";
sheet.Cells[1, 9].Value = "iCachDanh";
sheet.Cells[1, 10].Value = "PhamViTanCong";
sheet.Cells[1, 11].Value = "SoLuotDanh";
sheet.Cells[1, 12].Value = "SoGiay";
sheet.Cells[1, 13].Value = "iStatusSkill";
sheet.Cells[1, 14].Value = "SoLanCongKich";
sheet.Cells[1, 15].Value = "LevelRestriction";
sheet.Cells[1, 16].Value = "PointLearnSkill";
sheet.Cells[1, 17].Value = "PointUpdateSkill";
sheet.Cells[1, 18].Value = "MaxSkillLevel";
sheet.Cells[1, 19].Value = "SkillIdRequired";
sheet.Cells[1, 20].Value = "iLoaiHinhCongKich_";
sheet.Cells[1, 21].Value = "iPhanBietKyNang";
sheet.Cells[1, 22].Value = "SkillIdCanLearn";
sheet.Cells[1, 23].Value = "uEquip3";
sheet.Cells[1, 24].Value = "uEquip4";
sheet.Cells[1, 25].Value = "uEquip5";
sheet.Cells[1, 26].Value = "Description";
for (int i = 1; i < iTotalBlock; i++)
{
TsOnline.Entity.SkillEntity item = new TsOnline.Entity.SkillEntity();
int index = i * iBlock;
item.LengthSkillName = buffer[index++];
Array.Reverse(buffer, index, 20);
sheet.Cells[i + 1, 1].Value = item.SkillName = Encoding.Default.GetString(buffer, index, item.LengthSkillName).Trim();
index += 20;
sheet.Cells[i + 1, 2].Value = item.iSkillCategory = (EnumSkillCategory)ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 3].Value = item.SkillID= ProgressUshort(BitConverter.ToUInt16(buffer, index));
index += 2;
sheet.Cells[i + 1, 4].Value = item.SP = ProgressUshort(BitConverter.ToUInt16(buffer, index));
index += 2;
sheet.Cells[i + 1, 5].Value = item.iElement = (EnumElement)ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 6].Value = item.NumberElement = ProgressInt(BitConverter.ToInt32(buffer, index));
index += 4;
sheet.Cells[i + 1, 7].Value = item.ValueElement = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 8].Value = item.Level = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 9].Value = item.iCachDanh = (EnumSkillTypeStatus)ProgressByte(buffer[index++]);
sheet.Cells[i + 1,10].Value = item.PhamViTanCong = (EnumCategoryRangeAttack)ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 11].Value = item.SoLuotDanh = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 12].Value = item.SoGiay = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 13].Value = item.iStatusSkill = (EnumSkillStatus)ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 14].Value = item.SoLanCongKich = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 15].Value = item.LevelRestriction = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 16].Value = item.PointLearnSkill = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 17].Value = item.PointUpdateSkill = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 18].Value = item.MaxSkillLevel = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 19].Value = item.SkillIdRequired = ProgressUshort(BitConverter.ToUInt16(buffer, index));
index += 2;
sheet.Cells[i + 1, 20].Value = item.iLoaiHinhCongKich_ = (EnumTypeAttack)ProgressUshort(BitConverter.ToUInt16(buffer, index));
index += 2;
sheet.Cells[i + 1, 21].Value = item.iPhanBietKyNang = (EnumPhanBietSkill)ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 22].Value = item.SkillIdCanLearn = ProgressUshort(BitConverter.ToUInt16(buffer, index));
index += 2;
sheet.Cells[i + 1, 23].Value = item.uEquip3 = ProgressByte(buffer[index++]);
sheet.Cells[i + 1, 24].Value = item.uEquip4 = ProgressUshort(BitConverter.ToUInt16(buffer, index));
index += 2;
sheet.Cells[i + 1, 25].Value = item.uEquip5 = ProgressUshort(BitConverter.ToUInt16(buffer, index));
index += 2;
item.LengthDescription = buffer[index++];
Array.Reverse(buffer, index, 30);
sheet.Cells[i + 1, 26].Value = item.Description = Encoding.Default.GetString(buffer, index, item.LengthDescription).Trim();
listData.Add(item);
raiseSendMessage(string.Format("Skill.Dat: {0}/{1}", i, iTotalBlock - 1));
raiseProgress(i * 100 / iTotalBlock);
}
}
}
private byte ProgressByte(byte input)
{
return (byte)(((input ^ 0xFD) & 0xFF) - 4);
}
private ushort ProgressUshort(ushort input)
{
return (ushort)((input ^ 0x6EA0) - 4);
}
private int ProgressInt(int input)
{
return (int)((input ^ 0xBDEDEBF) - 4);
}
24/9/2013: Có bạn hỏi tôi, muốn làm server game cần những gì, đây tôi nêu 1 số kiến thức trong khả năng có hạn của tôi.
1. Kiến thức lập trình căn bản, và ngôn ngữ lập trình chỉ cần hỗ trợ lập trình socket.
2. Có chút kiến thức về packet. Vì việc đầu tiên không phải là phân tích packet đó làm gì, muh là packet đó có cấu trúc như thế nào.
3. Có chút kinh nghiệm về mã hóa. Như chụp packet khi đăng nhập, xem nó packet có giống nhau sau 2 lần chụp hay không...
4. Có chút kinh nghiệm về research. Thời buổi này bác Gu Gồ bự lắm, kiếm gì cũng có, quan trọng là phải biết kiếm đúng chỗ.
5. Kiếm chút tài liệu về asm để đọc, có thể đọc để debug ở mức căn bản, còn không làm được, thì ráng kiếm làm sao có Data của của game do các cao thủ nào leak ra, rồi sử dụng nó làm data căn bản.
6. Biết điểm dừng lại. Vì 1 người không thể làm hoàn chỉnh 1 server được đâu, nếu muôn học hỏi thì nên đưa target tầm ngắn thôi. Và đơn giản nhất là làm mấy cái BOT trước, vì BOT nó đơn giản hơn server game nhiều.
7. Nắm vững cấu trúc dữ liệu, vì "int A = 4;" khác với "byte A = 4".
.....
Còn nhiều, rất nhiều cái để nói, vài dòng trên đây không thể nói hết. Nếu anh em muốn gặp nhau chia sẽ kinh nghiệm ở TPHCM thì lúc nào cũng hoan nghênh. Vì kiến thức không thể phát triển nếu không chia sẽ.
Chỉnh sửa cuối:



