📄 charasel.pas
字号:
unit CharaSel;
interface
uses
//Windows, Forms, Classes, SysUtils, Math, ScktComp, Common;
Windows, SysUtils, ScktComp, Common, SQLData,Database,FusionSQL;
//==============================================================================
// 娭悢掕媊
procedure sv2PacketProcess(Socket: TCustomWinSocket);
//==============================================================================
implementation
//==============================================================================
// 僉儍儔僙儗僒乕僶乕僷働僢僩張棟
procedure sv2PacketProcess(Socket: TCustomWinSocket);
var
cmd :word;
cnt :integer;
i,j,k,m :integer;
w :word;
l :cardinal;
id1 :cardinal;
id2 :cardinal;
b :byte;
bb :array[0..5] of byte;
len :integer;
str1 :string;
tp :TPlayer;
tc :TChara;
count:integer;
{NPC僀儀儞僩捛壛}
mi :MapTbl;
tg :TGuild;
tc1 :TChara;
{NPC僀儀儞僩捛壛僐僐傑偱}
begin
len := Socket.ReceiveLength;
if len >= 2 then begin
Socket.ReceiveBuf(buf, len);
RFIFOW(0, cmd);
case cmd of
$0065: //僉儍儔僙儗嶪愙懕梫媮
begin
RFIFOL( 2, l);
str1 := IntToStr(l);
RFIFOL( 6, id1);
RFIFOL(10, id2);
if Player.IndexOf(l) <> -1 then begin
tp := Player.IndexOfObject(l) as TPlayer;
// Character Loads should be in Character Select Area
// Speeds up login time, needed especially for SQL
if UseSQL then Call_Characters(tp.ID);
if tp.Login = 1 then begin
count := 0;
while count < 8 do begin
if (tp.CData[count] <> nil)and(tp.CData[count].Login <> 0) then begin
WFIFOW(0, $0081);
WFIFOB(2, 08);
Socket.SendBuf(buf, 3);
tp.Login := 0;
tp.CData[count].Login := 0;
end;
inc(count);
end;
end;
//if tp.IP = Socket.RemoteAddress then begin
if (tp.LoginID1 = id1) and (tp.LoginID2 = id2) and (tp.LoginID1 <> 0) then begin
Socket.Data := tp;
WFIFOL(0, $00000000);
Socket.SendBuf(buf, 4);
ZeroMemory(@buf[4], 24);
WFIFOW(0, $006b);
cnt := 0;
if tp.ver2 = 9 then w := 24 else w := 4;
if tp.ver2 = 9 then j := 5 else j := 3;
for i := 0 to j - 1 do begin
if tp.CData[i] <> nil then begin
ZeroMemory(@buf[w+(cnt*106)], 106);
tc := tp.CData[i];
tc.IP := Socket.RemoteAddress;
tc.tmpMap := '';
CalcStat(tc);
for k := 1 to MAX_SKILL_NUMBER do begin
tc.Skill[k].Tick := 0;
end;
tc.SkillTick := $FFFFFFFF;
tc.Option := tc.Option and $DFFE;
if (tc.Option and 6 <> 0) then begin
tc.Option := tc.Option and $FFF9;
tc.Hidden := false;
end;
tc.Stat1 := 0;
tc.Stat2 := 0;
with tc do begin
WFIFOL(w+(cnt*106)+ 0, CID);
WFIFOL(w+(cnt*106)+ 4, BaseEXP);
WFIFOL(w+(cnt*106)+ 8, Zeny);
WFIFOL(w+(cnt*106)+ 12, JobEXP);
WFIFOL(w+(cnt*106)+ 16, JobLV);
WFIFOL(w+(cnt*106)+ 20, 0);
WFIFOL(w+(cnt*106)+ 24, 0);
WFIFOL(w+(cnt*106)+ 28, Option);
WFIFOL(w+(cnt*106)+ 32, Karma);
WFIFOL(w+(cnt*106)+ 36, Manner);
WFIFOW(w+(cnt*106)+ 40, StatusPoint);
WFIFOW(w+(cnt*106)+ 42, HP);
WFIFOW(w+(cnt*106)+ 44, MAXHP);
WFIFOW(w+(cnt*106)+ 46, SP);
WFIFOW(w+(cnt*106)+ 48, MAXSP);
WFIFOW(w+(cnt*106)+ 50, Speed);
WFIFOW(w+(cnt*106)+ 52, JID);
WFIFOW(w+(cnt*106)+ 54, Hair);
WFIFOW(w+(cnt*106)+ 56, Weapon);
WFIFOW(w+(cnt*106)+ 58, BaseLV);
WFIFOW(w+(cnt*106)+ 60, SkillPoint);
WFIFOW(w+(cnt*106)+ 62, Head3); //Head
WFIFOW(w+(cnt*106)+ 64, Shield);
WFIFOW(w+(cnt*106)+ 66, Head1);
WFIFOW(w+(cnt*106)+ 68, Head2);
WFIFOW(w+(cnt*106)+ 70, HairColor);
WFIFOW(w+(cnt*106)+ 72, ClothesColor);
WFIFOS(w+(cnt*106)+ 74, Name, 24);
for k := 0 to 5 do
WFIFOB(w+(cnt*106)+98+k, ParamBase[k]);
WFIFOB(w+(cnt*106)+104, CharaNumber);
WFIFOB(w+(cnt*106)+105, 0);
Inc(cnt);
end;
end;
end;
WFIFOW(2, w + cnt * 106);
Socket.SendBuf(buf, w + cnt * 106);
end;
end;
end;
$0066: //僉儍儔僋僞慖戰梫媮
begin
if Socket.Data = nil then exit;
tp := Socket.Data;
{2廳儘僌僀儞僠僃僢僋}
count := 0;
while count < 8 do
begin
if (tp.CData[count] <> nil)and(tp.CData[count].Login <> 0) then
begin
//debugout.lines.add('[' + TimeToStr(Now) + '] ' + '2廳儘僌僀儞偝傟傑偟偨丅');
//2廳儘僌僀儞
WFIFOW( 0, $0081);
WFIFOB( 2, 08);
tp.CData[count].Socket.SendBuf(buf, 3);
end;
inc(count);
end;
{2廳儘僌僀儞僠僃僢僋丂偙偙傑偱}
RFIFOB(2, b);
if b > 4 then exit;
//if UseSQL then GetCharaPartyGuild(tp.CID[b]);
if tp.CData[b] <> nil then begin
tc := tp.CData[b];
if UseSQL then Load_Parties(tc.CID);
if UseSQL then Load_Pets(tc.ID);
if UseSQL then Load_Guilds(tc.CID);
{NPC僀儀儞僩捛壛}
i := MapInfo.IndexOf(tc.Map);
j := -1;
if (i <> -1) then begin
mi := MapInfo.Objects[i] as MapTbl;
if (mi.noSave = true) then j := 0;
end;
if (j = 0) then begin
tc.Map := tc.SaveMap;
tc.Point.X := tc.SavePoint.X;
tc.Point.Y := tc.SavePoint.Y;
end;
{NPC僀儀儞僩捛壛僐僐傑偱}
WFIFOW(0, $0071);
WFIFOL(2, tc.CID);
WFIFOS(6, tc.Map + '.rsw', 24);
WFIFOL(22, ServerIP);
WFIFOW(26, sv3port);
Socket.SendBuf(buf, 28);
end;
end;
$0067: //僉儍儔嶌惉梫媮
begin
if Socket.Data = nil then exit;
tp := Socket.Data;
//僗儘僢僩偑偁偄偰偄傞偐偳偆偐僠僃僢僋
RFIFOB(32, b);
if b > 4 then exit;
if tp.CData[b] <> nil then begin
WFIFOW(0, $006e);
WFIFOB(2, 2);
Socket.SendBuf(buf, 3);
exit;
end;
//僷儔儊乕僞偵晄惓偑側偄偐僠僃僢僋
b := 0;
for i := 0 to 5 do begin
RFIFOB(i+26, bb[i]);
if (bb[i] < 1) or (bb[i] > 9) then begin
WFIFOW(0, $006e);
WFIFOB(2, 2);
Socket.SendBuf(buf, 3);
exit;
end else begin
b := b + bb[i];
end;
end;
if b <> 30 then begin
WFIFOW(0, $006e);
WFIFOB(2, 2);
Socket.SendBuf(buf, 3);
exit;
end;
//柤慜偑婛偵巊傢傟偰偄側偄偐僠僃僢僋
str1 := RFIFOS(2, 24);
if UseSQL then begin
if CheckUserExist(str1) then begin
WFIFOW(0, $006e);
WFIFOB(2, 0);
Socket.SendBuf(buf, 3);
exit;
end;
end else begin
if CharaName.IndexOf(str1) <> -1 then begin
WFIFOW(0, $006e);
WFIFOB(2, 0);
Socket.SendBuf(buf, 3);
exit;
end;
end;
//僉儍儔僨乕僞嶌惉
tc := TChara.Create;
with tc do begin
ID := tp.ID;
Gender := tp.Gender;
if UseSQL then CID := GetNowCharaID()
else begin
{傾僀僥儉惢憿娭學捛壛}
if CID < 100001 then CID := CID + 100001;
{傾僀僥儉惢憿娭學捛壛}
if CID >= NowCharaID then NowCharaID := CID + 1;
CID := NowCharaID;
Inc(NowCharaID);
end;
Name := str1;
Gender := tp.Gender;
JID := 0;
BaseLV := 1;
BaseEXP := 0;
StatusPoint := 0;
JobLV := 1;
JobEXP := 0;
SkillPoint := 0;
Zeny := DefaultZeny;
for i := 0 to 5 do
ParamBase[i] := bb[i];
DefaultSpeed := 150;
RFIFOB(35, b);
if b > 19 then begin //敮宆偑晄惓
WFIFOW(0, $006e);
WFIFOB(2, 2);
Socket.SendBuf(buf, 3);
tc.Free;
exit;
end;
Hair := b;
RFIFOB(33, b);
if b > 8 then begin //敮偺怓偑晄惓
WFIFOW(0, $006e);
WFIFOB(2, 2);
Socket.SendBuf(buf, 3);
tc.Free;
exit;
end;
HairColor := b;
ClothesColor := 0;
RFIFOB(32, CharaNumber);
Map := DefaultMap;
Point.X := DefaultPoint_X;
Point.Y := DefaultPoint_Y;
SaveMap := DefaultMap;
SavePoint.X := DefaultPoint_X;
SavePoint.Y := DefaultPoint_Y;
with Item[1] do begin
//DefaultItem1=1201
ID := DefaultItem1;
Amount := 1;
Equip := 2;
Identify := 1;
Refine := 0;
Attr := 0;
Card[0] := 0;
Card[1] := 0;
Card[2] := 0;
Card[3] := 0;
Data := ItemDB.IndexOfObject(DefaultItem1) as TItemDB;
end;
with Item[2] do begin
//DefaultItem2=2301
ID :=DefaultItem2;
Amount := 1;
Equip := 16;
Identify := 1;
Refine := 0;
Attr := 0;
Card[0] := 0;
Card[1] := 0;
Card[2] := 0;
Card[3] := 0;
Data := ItemDB.IndexOfObject(DefaultItem2) as TItemDB;
end;
for i := 0 to MAX_SKILL_NUMBER do begin
if SkillDB.IndexOf(i) <> -1 then begin
tc.Skill[i].Data := SkillDB.IndexOfObject(i) as TSkillDB;
end;
end;
SkillTick := $FFFFFFFF;
CalcStat(tc);
HP := MAXHP;
SP := MAXSP;
end;
if UseSQL then SaveCharaData(tc);
CharaName.AddObject(tc.Name, tc);
Chara.AddObject(tc.CID, tc);
RFIFOB(32, b);
tp.CName[b] := tc.Name;
tp.CData[b] := tc;
//僉儍儔僨乕僞憲怣
with tc do begin
WFIFOW(0, $006d);
WFIFOL(2+ 0, CID);
WFIFOL(2+ 4, BaseEXP);
WFIFOL(2+ 8, Zeny);
WFIFOL(2+ 12, JobEXP);
WFIFOL(2+ 16, JobLV);
WFIFOL(2+ 20, 0);
WFIFOL(2+ 24, 0);
WFIFOL(2+ 28, Option);
WFIFOL(2+ 32, Karma);
WFIFOL(2+ 36, Manner);
WFIFOW(2+ 40, StatusPoint);
WFIFOW(2+ 42, HP);
WFIFOW(2+ 44, MAXHP);
WFIFOW(2+ 46, SP);
WFIFOW(2+ 48, MAXSP);
WFIFOW(2+ 50, Speed);
WFIFOW(2+ 52, JID);
WFIFOW(2+ 54, Hair);
WFIFOW(2+ 56, Weapon);
WFIFOW(2+ 58, BaseLV);
WFIFOW(2+ 60, SkillPoint);
WFIFOW(2+ 62, Head3);
WFIFOW(2+ 64, Shield);
WFIFOW(2+ 66, Head1);
WFIFOW(2+ 68, Head2);
WFIFOW(2+ 70, HairColor);
WFIFOW(2+ 72, ClothesColor);
WFIFOS(2+ 74, Name, 24);
for i := 0 to 5 do
WFIFOB(2+98+i, ParamBase[i]);
WFIFOB(2+104, CharaNumber);
WFIFOB(2+105, 0);
end;
Socket.SendBuf(buf, 108);
end;
$0068: //僉儍儔嶍彍梫媮
begin
if Socket.Data = nil then exit;
tp := Socket.Data;
RFIFOL(2, l);
str1 := RFIFOS(6, 40);
if str1 = tp.Mail then begin
i := Chara.IndexOf(l);
if (i <> -1) then begin
//嶍彍丅
tc := Chara.Objects[i] as TChara;
//for k := 0 to 4 do begin
for k := 0 to 2 do begin
if tp.CData[k] = tc then begin
tp.CName[k] := '';
tp.CData[k] := nil;
break;
end;
end;
{ Mitch 02-06-2004: Fix character delete/blank char in guild bug }
if (tc.GuildID <> 0) then begin
j := GuildList.IndexOf(tc.GuildID);
if (j <> -1) then begin
tg := GuildList.Objects[j] as TGuild;
if (tg.MasterName <> tc.Name) then begin
for k := tc.GuildPos to 35 do begin
tg.MemberID[k] := tg.MemberID[k + 1];
tg.Member[k] := tg.Member[k + 1];
tg.MemberPos[k] := tg.MemberPos[k + 1];
tg.MemberEXP[k] := tg.MemberEXP[k + 1];
end;
end else begin
//Lets delete all the members.
for k := 0 to 35 do begin
if tg.MemberID[k] <> 0 then begin
m := Chara.IndexOf(tg.MemberID[k]);
if m <> -1 then begin
tc1 := Chara.Objects[m] as TChara;
tc1.GuildID := 0;
tc1.GuildPos := 0;
tc1.GuildName := '';
tc1.Classname := '';
end;
end;
end;
GuildList.Delete(j);
end;
end;
end;
if UseSQL then
DeleteChar(tc.CID);
CharaName.Delete(i);
Chara.Delete(i);
tc.Free;
WFIFOW(0, $006f);
Socket.SendBuf(buf, 2);
end else begin
//嶍彍偡傞僉儍儔偑尒偮偐傜側偄(嶍彍嫅斲傪曉偡)
WFIFOW(0, $0070);
WFIFOB(2, 1);
Socket.SendBuf(buf, 3);
end;
end else begin
//儊乕儖傾僪儗僗偑堘偆
WFIFOW(0, $0070);
WFIFOB(2,0);
Socket.SendBuf(buf, 3);
end;
end;
end;
end;
end;
//==============================================================================
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -