www.pudn.com > M2Server.rar > UserInfo.pas


//////////////////////////////////////////////////////////////////////////////// 
//                                                                            // 
//                       工程:  M2Server                                     // 
//                       版本:   1.0                                          // 
//                       公司:  乐都在线                                     // 
//                       网址:  http://www.hh8.net                           // 
//                       日期:  2005-05-28                                   // 
//                                                                            // 
//////////////////////////////////////////////////////////////////////////////// 
unit UserInfo; 
 
interface 
 
uses 
  Windows, Classes, SysUtils, StrUtils, IdWinSock2, PredefinedData, 
    ClassDeclaration, Contnrs, D7ScktComp; 
 
type 
  TGateInfo = class 
  public 
    m_Socket: TSocket; 
    Socket: TCustomWinSocket; 
    PeerIP: string; 
    sSocData: string; 
    m_fDoSending: Boolean; 
    m_xSendBuffQ: TList; 
    m_nIndex: Integer; 
    //   m_OverlappedEx   : array [0..1] of TOVERLAPPEDEX_RCD; 
  public 
    constructor Create; 
    procedure SendGateCheck; 
    procedure OpenNewUser(pszPacket: PChar); 
    procedure xSend; 
    // function    Send(lpSendBuff:  PSENDBUFF_RCD): Integer; 
 
  end; 
 
  TUserInfo = class 
  public 
    m_bEmpty: Boolean; 
    m_Socket: Integer; 
    m_szUserID: string[12]; 
    m_szCharName: string[14]; 
    m_addr: string[15]; 
    m_nUserGateIndex: Integer; 
    m_nUserServerIndex: Integer; 
    m_nCertification: Integer; 
    m_nClientVersion: Integer; 
    m_pxPlayerObject: TObject; 
    m_pGateInfo: TGateInfo; 
    m_btCurrentMode: Byte; 
    m_THumanRcd: THUMAN_RCD; 
 
    m_BagItems: TList; 
    m_TakeItems: array[0..12] of tClientItem; 
    m_TakeItemsCount: Integer; 
    m_Magic: TList; 
 
    m_lpTMagicRcd: TThreadList; 
 
 
    m_lpTMagicErgumSkill: PHUMANMAGIC_RCD; 
    m_fLongHitSkill: Boolean; 
    m_lpTMagicBanwolSkill: PHUMANMAGIC_RCD; 
    m_fWideHitSkill: Boolean; 
    m_lpTMagicFireSwordSkill: PHUMANMAGIC_RCD; 
    m_fFireHitSkill: Boolean; 
    m_dwLatestFireHitTime: LongWord; 
 
    m_lpTMagicOneSwordSkill: PHUMANMAGIC_RCD; 
    m_lpTMagicIlkwangSkill: PHUMANMAGIC_RCD; 
 
    m_lpTMagicPowerHitSkill: PHUMANMAGIC_RCD; 
    m_fPowerHitSkill: Boolean; 
 
    m_btAttackSkillCount: Byte; 
    m_btAttackSkillPointCount: Byte; 
 
    m_lpTHorseRcd: PHORSE_RCD; 
    Npc: PTNpcScript; 
    NpcStr, goodsstr: string; 
  public 
    constructor Create; 
    function ScriptNpc(FileName: string): Boolean; 
    function RunAct(Act: string): string; 
    function RunCommand(Command: string): Boolean; 
    function IsEmpty: Boolean; 
    procedure AddNewItem(pszItemName: string); 
    procedure MakeGenItem(lptGenItemRcd: PGENERALITEM_RCD); 
    function GetDressFeature: Integer; 
    function GetWeaponFeature: Integer; 
    function GetItem(pszMakeIndex: Word): PUSERITEM; 
    function GetUseGenItem(pszMakeItemID: string): PGENERALITEM_RCD; 
    function IsMyMagic(nIndex: Integer): Boolean; 
    function EncodeMyMagicToServer(pszEncodeMsg: string; nBuffSize: Integer; var 
      nPos: Integer): Integer; 
    function EncodeMyMagic(var pszEncodeMsg: string; nBuffSize: Integer; var 
      nPos: Integer): Integer; 
    procedure RemoveGenItem(index: Integer); 
    procedure RemoveItem(ItemName: string); 
 
    function EncodeGenItem(pszEncodeMsg: string; nBuffSize: Integer; var nPos: 
      Integer): Integer; 
    procedure AllowLongHitSkill(fFlag: Boolean); 
    procedure AllowWideHitSkill(fFlag: Boolean); 
    function AllowFireHitSkill: Boolean; 
    function GetGenItemStdIdx(pszMakeIndex: string): Integer; 
    function GetGenItemVal1(pszMakeIndex: string): Integer; 
    function GetGenItemVal2(pszMakeIndex: string): Integer; 
    function CalcBagWeight: Integer; 
    function CalcWearWeightEx(nIndex: Integer): Integer; 
    function UserDropItem(nItemIndex: Integer; pszMakeIndex: string): Boolean; 
    function UserDropGenItem(nItemIndex: Integer; pszMakeIndex: string): 
      Boolean; 
    function IncGold(nGold: Integer): Boolean; 
    function DecGold(nGold: Integer): Boolean; 
    function GetMagicRcdByKey(nKey: Integer): PHUMANMAGIC_RCD; 
    function GetMagicRcdByID(nID: Integer): PHUMANMAGIC_RCD; 
    function CanUseBujuk: PGENERALITEM_RCD; 
    procedure ProcessUserMessage(pszPacket: PChar; nLen: Integer); 
    procedure Operate; 
    procedure CloseUserHuman(step: Integer); 
    procedure SaveHumanToDB(step: Integer); 
    procedure CloseAccount(pszName: string; nCertification: Integer); 
    procedure DoClientCertification(pszPacket: string); 
 
    function GetUserItem(nPosition: Integer): PUSERITEM; 
    function GetWeapon: PUSERITEM; 
    procedure SetEmptyWeapon; 
    procedure SetEmptyDress; 
    procedure SetEmptyUseItem(I: Integer); 
    function GetDress: PUSERITEM; 
    function GetAccessory(nPosition: Integer): PUSERITEM; 
    function GetRightHand: PGENERALITEM_RCD; 
    function GetGenderFeature: Byte; 
    function GetHairFeature: Byte; 
    function GetHorseFeatureEx: Byte; 
    function GetJob: Integer; 
    procedure SetJob(nJob: Integer); 
    function GetAttackMode: Integer; 
    function GetMagicID(MagicName: string): Integer; 
    function IsEnoughBag: Boolean; 
    function GetGold: LongWord; 
    function GetPK: Integer; 
    function GetLuck: Integer; 
    function GetItemNum(ItemName: string): Integer; 
    function GetItemByName(ItemName: string): PTCLIENTITEM; 
  end; 
 
  TReadyUserInfo = class 
  public 
    m_szUserID: string[10]; 
    m_szCharName: string[140]; 
    m_fStartNew: Boolean; 
    m_nCertification: Integer; 
    m_nApprovalMode: Integer; 
    m_nClientVersion: Integer; 
    m_s: TSocket; 
    m_nUserGateIndex: Integer; 
    m_pGateInfo: TGateInfo; 
    m_pUserInfo: TUserInfo; 
    m_dwReadyStartTime: LongWord; 
    m_fClosed: Boolean; 
  end; 
  TReadyUserInfo2 = class 
  public 
    m_fStartNew: Boolean; 
    m_dwReadyStartTime: LongWord; 
    m_nNumOfGenItem: Integer; 
    m_nNumOfItem: Integer; 
    m_nNumOfMagic: Integer; 
    m_THumanRcd: THUMAN_RCD; 
    pszData: array[1..8096] of Char; 
  end; 
 
implementation 
 
uses ObjectPlayer, GlobalDefinition, ProcessThreads, FunctionDeclaration, 
  ObjectEngine, DataHandler, EDcode, MainForm; 
 
constructor TGateInfo.Create; 
begin 
  m_fDoSending := False; 
  m_xSendBuffQ := TList.Create; 
  Socket := nil; 
  PeerIP := ''; 
end; 
 
{校正 Gate} 
procedure TGateInfo.SendGateCheck; 
var 
  MsgHdr: TMSGHEADER_RCD; 
  lpSendBuff: array[0..20] of Char; 
begin 
 
 
  if lpSendBuff <> nil then 
  begin 
    MsgHdr.nCode := $AA55AA55; 
    MsgHdr.nSocket := 0; 
    MsgHdr.wUserGateIndex := 0; 
    MsgHdr.wIdent := GM_CHECKSERVER; 
    MsgHdr.wUserListIndex := 0; 
    MsgHdr.wTemp := 0; 
    MsgHdr.nLength := 0; 
 
 
    Move(MsgHdr, lpSendBuff, 20); 
    Socket.SendBuf(lpSendBuff, 20); 
    //    FreeMem(lpSendBuff); 
  end; 
end; 
 
{打开新角色} 
procedure TGateInfo.OpenNewUser(pszPacket: PChar); 
var 
  nIndex: Integer; 
  MsgHdr: TMSGHEADER_RCD; 
  lpMsgHeader: PMSGHEADER_RCD; 
  pUserInfo: TUserInfo; 
  lpSendBuff: array[0..4000] of Char; 
  dwBytesSends: LongWord; 
  Findok: Boolean; 
  SMG: string; 
  DefMsg: TDEFAULTMESSAGE_RCD; 
begin 
  Findok := False; 
  for nIndex := 0 to 4999 do       //创建一个新的TUserInfo对象 
  begin 
    if g_xUserInfoArr[nIndex] = nil then 
    begin 
      g_xUserInfoArr[nIndex] := TUserInfo.Create; 
      Findok := True; 
    end 
    else if g_xUserInfoArr[nIndex].m_bEmpty then 
      Findok := True; 
 
 
    if Findok then 
    begin 
      pUserInfo := g_xUserInfoArr[nIndex]; 
      lpMsgHeader := PMSGHEADER_RCD(pszPacket); 
      pUserInfo.m_btCurrentMode := 0; 
      pUserInfo.m_Socket := lpMsgHeader^.nSocket; 
      pUserInfo.m_pxPlayerObject := nil; 
      ZeroMemory(@pUserInfo.m_szUserID[1], SizeOf(pUserInfo.m_szUserID)); 
      ZeroMemory(@pUserInfo.m_szCharName[1], SizeOf(pUserInfo.m_szCharName)); 
      pUserInfo.m_addr := Strpas(pszPacket + 20); 
      pUserInfo.m_nCertification := 0; 
      pUserInfo.m_nClientVersion := 0; 
      pUserInfo.m_nUserGateIndex := lpMsgHeader^.wUserGateIndex; 
      pUserInfo.m_nUserServerIndex := nIndex; 
      pUserInfo.m_pGateInfo := self; 
      pUserInfo.m_btCurrentMode := USERMODE_NOTICE; 
      pUserInfo.m_lpTHorseRcd := nil; 
      pUserInfo.m_bEmpty := False; 
 
      MsgHdr.nCode := $AA55AA55; 
      MsgHdr.nSocket := lpMsgHeader^.nSocket; 
      MsgHdr.wUserGateIndex := lpMsgHeader^.wUserGateIndex; 
      MsgHdr.wIdent := GM_SERVERUSERINDEX; 
      MsgHdr.wUserListIndex := nIndex; 
      MsgHdr.wTemp := 0; 
      MsgHdr.nLength := 0; 
      Move(MsgHdr, lpSendBuff, 20); 
      Socket.SendBuf(lpSendBuff, 20); 
      Exit; 
    end; 
  end; 
end; 
 
procedure TGateInfo.xSend; 
var 
  I: Integer; 
  dwBytesSends: LongWord; 
  nPos: Integer; 
  lpSendBuff: PSENDBUFF_RCD; 
  SendBuffer: PChar; 
begin 
  if m_xSendBuffQ.COunt > 0 then 
  begin 
    dwBytesSends := 0; 
    nPos := 0; 
    SendBuffer := nil; 
    for I := m_xSendBuffQ.COunt - 1 downto 0 do // Iterate 
    begin 
      lpSendBuff := m_xSendBuffQ.items[0]; 
      //      ReallocMem(SendBuffer,nPos + lpSendBuff^.nLen); 
      Socket.SendText(lpSendBuff^.szData); 
      m_xSendBuffQ.Delete(0); 
      //    CopyMemory(@SendBuffer[npos], @lpSendBuff^.szData[1], lpSendBuff^.nLen); 
      //    nPos        := nPos + lpSendBuff^.nLen; 
 
      Dispose(lpSendBuff); 
 
      //  if nPos >= 8192 then 
      //  begin 
      //    Break; 
       // end; 
    end; // for 
 
    {  if nPos > 0 then 
      begin 
         Socket.SendBuf(SendBuffer^,nPos); 
         FreeMem(SendBuffer); 
      end; 
    } 
  end; 
end; 
 
{function  TGateInfo.Send(lpSendBuff: PSENDBUFF_RCD):  Integer; 
var 
  nPos, 
  nRet:         Integer; 
  dwBytesSends: LongWord; 
  lpSBuff:      PSENDBUFF_RCD; 
  SendBuffer   :PCHar; 
begin 
  dwBytesSends  := 0; 
  nPos          := 0; 
  nRet          := 0; 
 
  if lpSendBuff <> nil then 
  begin 
    m_xSendBuffQ.add(lpSendBuff); 
  end; 
 
  if m_fDoSending then 
  begin 
    Result  := 0; 
    Exit; 
  end; 
  if m_xSendBuffQ.Count>0 then 
  Begin 
    lpSBuff   := m_xSendBuffQ.Items[0]; 
     m_xSendBuffQ.Delete(0); 
  End 
  else 
  begin 
    Result  := 0; 
    Exit; 
  end; 
  SendBuffer:=nil; 
  while lpSBuff <> nil do 
  begin 
 
    ReallocMem(SendBuffer,nPos + lpSBuff^.nLen); 
    CopyMemory(@SendBuffer[npos], @lpSBuff^.szData[1], lpSBuff^.nLen); 
     nPos    := nPos + lpSBuff^.nLen; 
 
    DisPose(lpSBuff); 
    lpsBuff:=nil; 
    if nPos >= 4096 then 
    begin 
      Break; 
    end; 
    if m_xSendBuffQ.Count>0 then 
    Begin 
      lpSBuff   :=m_xSendBuffQ.Items[0]; 
      m_xSendBuffQ.Delete(0); 
    End; 
  end; 
 
  if nPos > 0 then 
  begin 
 
    Socket.SendBuf(SendBuffer^,nPos); 
    FreeMem(SendBuffer); 
 
  end; 
 
  Result  := nRet; 
end; 
 } 
 
 
 
constructor TUserInfo.Create; 
begin 
  m_bEmpty := True; 
 
  m_pxPlayerObject := nil; 
  m_pGateInfo := nil; 
 
  m_lpTMagicRcd := TThreadList.Create; 
 
  m_lpTMagicErgumSkill := nil; 
  m_lpTMagicBanwolSkill := nil; 
  m_lpTMagicFireSwordSkill := nil; 
  m_lpTMagicOneSwordSkill := nil; 
  m_lpTMagicIlkwangSkill := nil; 
  m_lpTMagicPowerHitSkill := nil; 
  m_fLongHitSkill := False; 
  m_fWideHitSkill := False; 
  m_fFireHitSkill := False; 
  m_dwLatestFireHitTime := 0; 
 
 
  m_BagItems := TList.Create; 
 
  m_Magic := TList.Create; 
 
 
end; 
 
{加载指定的NPC} 
function TUserInfo.ScriptNpc(FileName: string): Boolean; 
var 
  FileNpc: Tstrings; 
  TempList: Tstrings; 
  I, j, ii, COunt, index, code, err: Integer; 
  Str, tempstr, str1: string; 
  isMain: Boolean; 
  sellindex, actindex: Integer; 
  IsGoods: Boolean; 
  GoodsCount: Integer; 
  Say: PChar; 
  cu: PTCLIENTITEM; 
  itemindex: Integer; 
begin 
  try 
    FileNpc := TStringList.Create; 
    FileNpc.LoadFromFile(FileName); 
    COunt := FileNpc.COunt; 
    if COunt = 0 then 
      Exit; 
    SetLength(Npc.Script, COunt); 
    SetLength(Npc.SellType, 10); 
    TempList := TStringList.Create; 
    index := -1; 
    sellindex := -1; 
    isMain := False; 
    IsGoods := False; 
    GoodsCount := 0; 
    SetLength(Npc.Goods, 1000); 
    Npc.Price := 100; 
    for I := 0 to COunt - 1 do 
    begin 
      Str := FileNpc.Strings[I]; 
      Str := TrimLeft(Str); 
      if Str = '' then 
        Continue; 
      case Str[1] of 
        '%': 
          begin 
            tempstr := Copy(Str, 2, Length(Str) - 1); 
            val(tempstr, code, err); 
            Npc.Price := code; 
          end; 
        '[': 
          begin 
            ArrestStringEx(Str, '[', ']', tempstr); 
            tempstr := UpperCase(tempstr); 
            if tempstr <> '' then 
            begin 
              if tempstr = 'GOODS' then 
                IsGoods := True 
              else 
              begin 
 
                if index >= 0 then 
                  SetLength(Npc.Script[index].Act, actindex + 1); 
 
                Inc(index); 
                Npc.Script[index].Name := tempstr; 
 
                SetLength(Npc.Script[index].Act, 100); 
                actindex := -1; 
                IsGoods := False; 
              end; 
              //         Npc.Script[index].Content:=''; 
            end; 
 
          end; 
        ';': ; 
        '+': 
          begin 
            tempstr := Copy(Str, 1, Length(Str) - 1); 
            if tempstr <> '' then 
            begin 
              Inc(sellindex); 
              val(tempstr, code, err); 
              Npc.SellType[sellindex] := code; 
            end; 
 
          end; 
      else 
        begin 
          if IsGoods then 
          begin 
            TempList.CommaText := Str; 
            if TempList.COunt > 2 then 
            begin 
              Npc.Goods[GoodsCount].Name := TempList.Strings[0]; 
              Npc.Goods[GoodsCount].SubMenu := StrToInt(TempList.Strings[1]); 
              itemindex := g_pStdItemHash.ValueOf(TempList.Strings[0]); 
              if (itemindex >= 0) and (itemindex <= High(g_pStdItemSpecial)) 
                then 
              begin 
                New(cu); 
                g_pStdItemSpecial[index].GetStandardItem(cu); 
                Npc.Goods[GoodsCount].Price := (cu^.s.Price * Npc.Price) div 
                  100; 
                Npc.Goods[GoodsCount].Stock := cu.Dura; 
                Dispose(cu); 
              end; 
              Inc(GoodsCount); 
            end; 
 
          end 
          else 
          begin 
 
            str1 := UpperCase(Str); 
            if (pos('#IF', str1) = 1) or (pos('#ELSE', str1) = 1) then 
            begin 
              Inc(actindex); 
              Npc.Script[index].Act[actindex].Name := str1; 
              Npc.Script[index].Act[actindex].CommandList := TStringList.Create; 
            end 
            else 
            begin 
              if index < 0 then 
                Continue; 
              if actindex >= 0 then 
              begin 
                GetValidStr3(Str, str1, [' ']); 
                str1 := LowerCase(str1); 
 
                if (pos('#act', str1) = 1) then 
                  Npc.Script[index].Act[actindex].CommandList.Add(Str) 
                else if WOrdList.ValueOf(str1) >= 0 then 
                  Npc.Script[index].Act[actindex].CommandList.Add(Str) 
                else if str1 <> '#say' then 
                  Npc.Script[index].Act[actindex].Say := 
                    Npc.Script[index].Act[actindex].Say + Str + #13#10; 
              end 
              else 
              begin 
 
                Npc.Script[index].Say := Npc.Script[index].Say + Str + #13#10; 
              end; 
            end; 
          end; 
        end; 
      end; 
    end; 
    SetLength(Npc.Script, index + 1); 
    SetLength(Npc.Goods, GoodsCount); 
    if sellindex < 0 then 
      sellindex := 0; 
    SetLength(Npc.SellType, sellindex); 
  finally 
    TempList.Free; 
  end; 
end; 
 
{运行命令} 
function TUserInfo.RunCommand(Command: string): Boolean; 
var 
  I, index: Integer; 
  str1, Str, X, Y: string; 
  COunt, iCount, code: Integer; 
  cu: PTCLIENTITEM; 
 
  m_Ability: TOBJECTABILITY_RCD; 
begin 
  Result := False; 
  Command := GetValidStr3(Command, str1, [' ']); 
  str1 := LowerCase(str1); 
  index := WOrdList.ValueOf(str1); 
  //  m_Ability:=TPlayerObject(m_pxPlayerObject).m_Ability; 
  if index = -1 then 
    Exit; 
  case index of 
    0: //检测职业  checkjob (warr,wizard,taos); 
      begin 
        Command := LowerCase(Command); 
        Str := ''; 
        case m_THumanRcd.btJob of 
          0: Str := 'warr'; 
          1: Str := 'wizard'; 
          2: Str := 'taos'; 
        end; 
        if Str = Command then 
          Result := True; 
      end; 
    1: //检测金钱 
      begin 
        val(Command, COunt, code); 
        if COunt <= m_THumanRcd.dwGold then 
          Result := True; 
      end; 
    2: //检测等级 
      begin 
        Str := IntToStr(m_Ability.Level); 
        if Str = Command then 
          Result := True; 
      end; 
    3: //检测物品数 
      begin 
        Command := GetValidStr3(Command, str1, [' ']); 
        iCount := 0; 
        val(Command, COunt, code); 
        iCount := GetItemNum(str1); 
        if iCount >= COunt then 
          Result := True; 
 
      end; 
    4: //给物品 
      begin 
        Command := GetValidStr3(Command, str1, [' ']); 
        str1 := LowerCase(str1); 
        if str1 = '金币' then 
        begin 
          val(Command, COunt, code); 
          IncGold(COunt); 
        end 
        else 
        begin 
          AddNewItem(str1); 
        end; 
        Result := True; 
      end; 
    5: //取物品 
      begin 
        Command := GetValidStr3(Command, str1, [' ']); 
        str1 := LowerCase(str1); 
        if str1 = '金币' then 
        begin 
          val(Command, COunt, code); 
          DecGold(COunt); 
        end 
        else 
        begin 
          RemoveItem(str1); 
        end; 
        Result := True; 
      end; 
    6: //检测pk值 
      begin 
        iCount := GetPK; 
        val(Command, COunt, code); 
        if iCount >= COunt then 
          Result := True; 
 
      end; 
    7: //检测幸运值 
      begin 
        iCount := GetLuck; 
        val(Command, COunt, code); 
        if iCount >= COunt then 
          Result := True; 
      end; 
    8: //检测物品品质 
      begin 
        Command := GetValidStr3(Command, str1, [' ']); 
        iCount := 0; 
        val(Command, COunt, code); 
        cu := GetItemByName(str1); 
        if cu <> nil then 
        begin 
          iCount := cu.Dura div 1000; 
          if iCount > COunt then 
            Result := True; 
        end; 
 
      end; 
    9: //检测地图人数 
      begin 
        Command := GetValidStr3(Command, str1, [' ']); 
        val(Command, COunt, code); 
        iCount := GetMapHum(str1); 
        if iCount >= COunt then 
          Result := True; 
 
      end; 
    10:   //移动到这个地图的指定坐标 
      begin 
        Command := GetValidStr3(Command, Str, [' ']); 
        Command := GetValidStr3(Command, X, [' ']); 
        Command := GetValidStr3(Command, Y, [' ']); 
        TPlayerObject(m_pxPlayerObject).CmdFreeSpaceMove(Str, X, Y); 
      end; 
    11:   //移动到这个地图 
      begin 
        TPlayerObject(m_pxPlayerObject).CmdRandomSpaceMove(Command); 
      end; 
    19: //检测背包是否满 
      begin 
        Result := IsEnoughBag; 
      end; 
    28: 
      begin 
        RunAct(Command); 
      end; 
    29: Result := True; 
    30: 
      begin 
 
      end; 
  end; 
 
end; 
 
{运行NPC动作} 
function TUserInfo.RunAct(Act: string): string; 
var 
  I, j, ii: Integer; 
  Can: Boolean; 
  Str: string; 
 
begin 
  NpcStr := ''; 
  if UpperCase(Act) = '@BUY' then 
  begin 
    goodsstr := ''; 
    for I := 0 to High(Npc.Goods) do 
    begin 
      if Npc.Goods[I].items.COunt > 0 then 
        goodsstr := goodsstr + Format('%s/%d/%d/%d/', [Npc.Goods[I].Name, 
          Npc.Goods[I].SubMenu, Npc.Goods[I].Price, Npc.Goods[I].Stock]); 
    end; 
 
  end; 
  for I := 0 to High(Npc.Script) do 
  begin 
    if UpperCase(Npc.Script[I].Name) = UpperCase(Act) then 
    begin 
      if Npc.Script[I].Say <> '' then 
        NpcStr := Npc.Script[I].Say 
      else 
      begin 
        for j := 0 to High(Npc.Script[I].Act) do 
        begin 
          Str := UpperCase(Npc.Script[I].Act[j].Name); 
          if Npc.Script[I].Act[j].Name = '#IF' then 
          begin 
            Can := True; 
            for ii := 0 to (Npc.Script[I].Act[j].CommandList.COunt - 1) do 
            begin 
              Can := Can and RunCommand((Npc.Script[I].Act[j].CommandList[ii])); 
              if not Can then 
                Break; 
 
            end; 
            if not Can then 
              Continue; 
 
          end 
          else if pos('#ELSE', Str) = 1 then 
          begin 
            Can := True; 
            for ii := 0 to (Npc.Script[I].Act[j].CommandList.COunt - 1) do 
            begin 
              Can := Can and RunCommand((Npc.Script[I].Act[j].CommandList[ii])); 
              if not Can then 
                Break; 
 
            end; 
            if not Can then 
              Continue; 
          end; 
 
 
 
          if Npc.Script[I].Act[j].Say <> '' then 
          begin 
            NpcStr := Npc.Script[I].Act[j].Say; 
            Exit; 
          end; 
        end; 
      end; 
 
      Exit; 
    end; 
 
  end; 
end; 
 
 
 
 
 
 
 
 
function TUserInfo.IsEmpty: Boolean; 
begin 
  Result := m_bEmpty; 
end; 
 
procedure TUserInfo.AddNewItem(pszItemName: string);  //添加新的物品 //Success 
var 
  index: Integer; 
  cu: PTCLIENTITEM; 
begin 
  if (m_TakeItemsCount + m_BagItems.COunt) > USERITEMMAX then 
  begin 
    Exit; 
  end; 
  index := g_pStdItemHash.ValueOf(pszItemName); 
  if (index >= 0) and (index <= High(g_pStdItemSpecial)) then 
  begin 
    New(cu); 
    g_pStdItemSpecial[index].GetStandardItem(cu); 
    cu.MakeIndex := GetMakeIndex; 
    m_BagItems.Add(cu); 
    TPlayerObject(m_pxPlayerObject).SendAddItem(cu); 
    FormMain.InsertLogMsg(m_szCharName + '制造 ' + cu^.s.Name + '  ' + 
      IntToStr(cu.MakeIndex)); 
  end; 
 
end; 
 
procedure TUserInfo.MakeGenItem(lptGenItemRcd: PGENERALITEM_RCD); 
var 
  nIdx: Integer; 
  GenItemRcd: TGENITEM_RCD; 
  tClientItemRcd: TCLIENTITEM_RCD; 
  SendDefMsg: TDEFAULTMESSAGE_RCD; 
  szItem, 
    szEncodeMsg: string; 
begin 
  SetLength(szEncodeMsg, 256); 
  if m_pxPlayerObject <> nil then 
  begin 
    // Make Item on Server 
    szItem := StringReplace(Format('G%3d%4d%4d', [lptGenItemRcd^.nStdIndex, 
      lptGenItemRcd^.nDura, lptGenItemRcd^.nDuraMax]), ' ', '0', [rfReplaceAll]); 
    CopyMemory(@GenItemRcd.szItem[1], @szItem[1], 12); 
    CopyMemory(@lptGenItemRcd^.szMakeIndex[1], @GenItemRcd.szItem[1], 12); 
 
 
 
    SendDefMsg := MakeDefaultMsg(SM_ADDITEM, Integer(m_pxPlayerObject), 0, 0, 
      1); 
 
    // Get Standard General Item (STDITEM_ETC) 
    g_pStdItemEtc[lptGenItemRcd^.nStdIndex].GetStandardItem(@tClientItemRcd); 
 
    CopyMemory(@tClientItemRcd.szMakeIndex[1], @lptGenItemRcd^.szMakeIndex[1], 
      12); 
    tClientItemRcd.nDura := lptGenItemRcd^.nDura; 
    tClientItemRcd.nDuraMax := lptGenItemRcd^.nDuraMax; 
 
    szEncodeMsg := EncodeBuffer(@tClientItemRcd, SizeOf(TCLIENTITEM_RCD)); 
 
 
    TPlayerObject(m_pxPlayerObject).SendSocket(@SendDefMsg, szEncodeMsg); 
  end; 
end; 
 
{获取衣服信息} 
function TUserInfo.GetDressFeature: Integer; 
var 
  index, COunt: Integer; 
begin 
  Result := 0; 
  if m_TakeItems[0].MakeIndex > 0 then 
    begin 
      m_THumanRcd.szTakeItem[0].GoodId := 
        g_pStdItemHash.ValueOf(m_TakeItems[0].s.Name) + 1; 
    end; 
  index := m_THumanRcd.szTakeItem[0].GoodId - 1; 
  COunt := High(g_pStdItemSpecial); 
  if Index<0 then Index:=0; 
 
  if (index >= 0) and (index <= COunt) then 
  begin 
    Result := g_pStdItemSpecial[index].wShape * 2 + m_THumanRcd.Sex; 
  end; 
end; 
 
{获取武器信息} 
function TUserInfo.GetWeaponFeature: Integer; 
var 
  index, COunt: Integer; 
 
begin 
  Result := 0; 
  index := m_THumanRcd.szTakeItem[1].GoodId - 1; 
  COunt := High(g_pStdItemSpecial); 
  if (index >= 0) and (index <= COunt) then 
  begin 
    Result := g_pStdItemSpecial[index].wShape * 2 + m_THumanRcd.Sex; 
  end; 
end; 
 
{通过索引来获取物品} 
function TUserInfo.GetItem(pszMakeIndex: Word): PUSERITEM; 
var 
  index, COunt: Integer; 
begin 
  Result := nil; 
  index := m_THumanRcd.szTakeItem[pszMakeIndex].Id; 
  if (index > 0) then 
  begin 
    //  with m_lpTItemRcd do 
    //     Result:=Items[index]; 
      //m_lpTItemRcd.UnlockList; 
  end; 
end; 
 
function TUserInfo.GetUseGenItem(pszMakeItemID: string): PGENERALITEM_RCD; 
var 
  I: Integer; 
  lpTItemRcd: PGENERALITEM_RCD; 
begin 
  { with g_pStdItemSpecial do 
   begin 
     for I := 0 to Count - 1 do    // Iterate 
     begin 
       lpTItemRcd  := Items[I]; 
       if LeftBStr(pszMakeItemID, StrLen(PChar(pszMakeItemID))) = LeftBStr(lpTItemRcd^.szMakeIndex, StrLen(@lpTItemRcd^.szMakeIndex[1])) then 
       begin 
         Result  := lpTItemRcd; 
       //  m_lpTGenItemRcd.UnlockList; 
         Exit; 
       end; 
     end;    // for 
   end;    // with 
  // m_lpTGenItemRcd.UnlockList; 
 
   Result  := nil;     } 
end; 
 
function TUserInfo.IsMyMagic(nIndex: Integer): Boolean; 
var 
  I: Integer; 
  lptUserMagicRcd: PTClientMagic; 
begin 
  with m_lpTMagicRcd.LockList do 
  begin 
    for I := 0 to COunt - 1 do // Iterate 
    begin 
      lptUserMagicRcd := items[I]; 
      if lptUserMagicRcd^.Def.MagicID = nIndex then 
      begin 
        Result := True; 
        m_lpTMagicRcd.UnlockList; 
        Exit; 
      end; 
    end; // for 
  end; // with 
  m_lpTMagicRcd.UnlockList; 
 
  Result := False; 
end; 
 
function TUserInfo.EncodeMyMagicToServer(pszEncodeMsg: string; nBuffSize: 
  Integer; var nPos: Integer): Integer; 
var 
  I, 
    nCnt: Integer; 
  lptUserMagicRcd: PHUMANMAGIC_RCD; 
begin 
  nCnt := 0; 
  with m_lpTMagicRcd.LockList do 
  begin 
    for I := 0 to COunt - 1 do // Iterate 
    begin 
      lptUserMagicRcd := items[I]; 
      if lptUserMagicRcd <> nil then 
      begin 
        pszEncodeMsg := pszEncodeMsg + EncodeBuffer(PChar(lptUserMagicRcd), 
          SizeOf(THUMANMAGIC_RCD)); 
        pszEncodeMsg := pszEncodeMsg + '/'; 
        Inc(nPos); 
        Inc(nCnt); 
      end; 
    end; // for 
  end; // with 
  m_lpTMagicRcd.UnlockList; 
 
  Result := nCnt; 
end; 
 
function TUserInfo.EncodeMyMagic(var pszEncodeMsg: string; nBuffSize: Integer; 
  var nPos: Integer): Integer; 
var 
  I, 
    nCnt: Integer; 
  lptUserMagicRcd: PTClientMagic; 
  tClientMagicRcd: TClientMagic; 
begin 
  nCnt := 0; 
 
  with m_lpTMagicRcd.LockList do 
  begin 
    for I := 0 to COunt - 1 do // Iterate 
    begin 
      lptUserMagicRcd := items[I]; 
 
      if lptUserMagicRcd <> nil then 
      begin 
        tClientMagicRcd := lptUserMagicRcd^; 
 
        pszEncodeMsg := pszEncodeMsg + EncodeBuffer(@tClientMagicRcd, 
          SizeOf(TClientMagic)); 
 
        pszEncodeMsg := pszEncodeMsg + '/'; 
 
      end; 
    end; // for 
  end; // with 
  m_lpTMagicRcd.UnlockList; 
 
  Result := nCnt; 
end; 
 
{移除指定的物品} 
procedure TUserInfo.RemoveItem(ItemName: string); 
var 
  I: Integer; 
  cu: PTCLIENTITEM; 
begin 
  for I := 0 to m_BagItems.COunt - 1 do 
  begin 
    cu := PTCLIENTITEM(m_BagItems.items[I]); 
    if cu^.s.Name = ItemName then 
    begin 
      TPlayerObject(m_pxPlayerObject).SendDelItem(cu); 
      RemoveGenItem(I); 
      Exit; 
    end; 
 
  end; 
end; 
 
procedure TUserInfo.RemoveGenItem(index: Integer); 
var 
  I: Integer; 
 
begin 
  Dispose(m_BagItems.items[index]); 
  m_BagItems.Delete(index); 
 
end; 
 
function TUserInfo.EncodeGenItem(pszEncodeMsg: string; nBuffSize: Integer; var 
  nPos: Integer): Integer; 
var 
  I, 
    nCnt: Integer; 
  lptGenItemRcd: PGENERALITEM_RCD; 
  GenItemRcd: TGENITEM_RCD; 
  szItem: string; 
begin 
  nCnt := 0; 
 
 
end; 
 
procedure TUserInfo.AllowLongHitSkill(fFlag: Boolean); 
begin 
  m_fLongHitSkill := fFlag; 
 
  if m_fLongHitSkill then 
  begin 
    TPlayerObject(m_pxPlayerObject).SysMsg(IDS_ALLOW_LONGHIT, 1); 
  end 
  else 
  begin 
    TPlayerObject(m_pxPlayerObject).SysMsg(IDS_NOTALLOW_LONGHIT, 1); 
  end; 
end; 
 
procedure TUserInfo.AllowWideHitSkill(fFlag: Boolean); 
begin 
  m_fWideHitSkill := fFlag; 
 
  if m_fWideHitSkill then 
  begin 
    TPlayerObject(m_pxPlayerObject).SysMsg(IDS_ALLOW_WIDEHIT, 1); 
  end 
  else 
  begin 
    TPlayerObject(m_pxPlayerObject).SysMsg(IDS_NOTALLOW_WIDEHIT, 1); 
  end; 
end; 
 
function TUserInfo.AllowFireHitSkill: Boolean; 
begin 
  if (GetTickCount - m_dwLatestFireHitTime) > 10 * 1000 then 
  begin 
    m_fFireHitSkill := True; 
    m_dwLatestFireHitTime := GetTickCount; 
 
    TPlayerObject(m_pxPlayerObject).SysMsg(IDS_ALLOW_FIREHIT, 1); 
 
    Result := True; 
    Exit; 
  end 
  else 
  begin 
    TPlayerObject(m_pxPlayerObject).SysMsg(IDS_NOTALLOW_FIREHIT, 1); 
  end; 
 
  Result := False; 
end; 
 
function TUserInfo.GetGenItemStdIdx(pszMakeIndex: string): Integer; 
var 
  szStdIdx: string; 
begin 
  szStdIdx := midbstr(pszMakeIndex, 2, 3); 
 
  Result := StrToInt(szStdIdx); 
end; 
 
function TUserInfo.GetGenItemVal1(pszMakeIndex: string): Integer; 
var 
  szVal1: string; 
begin 
  szVal1 := midbstr(pszMakeIndex, 5, 4); 
 
  Result := StrToInt(szVal1); 
end; 
 
function TUserInfo.GetGenItemVal2(pszMakeIndex: string): Integer; 
var 
  szVal2: string; 
begin 
  szVal2 := midbstr(pszMakeIndex, 9, 4); 
 
  Result := StrToInt(szVal2); 
end; 
 
{计算当前负重} 
function TUserInfo.CalcBagWeight: Integer; 
var 
  I, 
    nWeight: Integer; 
  lpTItemRcd: PTCLIENTITEM; 
 
begin 
  nWeight := 0; 
  for I := 0 to m_BagItems.COunt - 1 do 
  begin 
    lpTItemRcd := PTCLIENTITEM(m_BagItems.items[I]); 
    if lpTItemRcd <> nil then 
      nWeight := nWeight + lpTItemRcd.s.Weight; 
  end; 
  Result := nWeight; 
end; 
 
{计算穿戴负重} 
function TUserInfo.CalcWearWeightEx(nIndex: Integer): Integer; 
var 
  I, 
    nWeight: Integer; 
  lpTItemRcd: PTCLIENTITEM; 
 
begin 
  nWeight := 0; 
  for I := 0 to 8 do 
  begin 
    if I = 1 then 
      Continue; //此时为腕力 
 
    if m_TakeItems[I].MakeIndex > 0 then 
      nWeight := nWeight + m_TakeItems[I].s.Weight; 
  end; 
  Result := nWeight; 
end; 
 
{丢掉物品} 
function TUserInfo.UserDropItem(nItemIndex: Integer; pszMakeIndex: string): 
  Boolean; 
var 
  I: Integer; 
  lpTItemRcd: PTCLIENTITEM; 
begin 
  if m_pxPlayerObject = nil then 
  begin 
    Result := False; 
  end; 
  for I := 0 to m_BagItems.COunt - 1 do 
  begin 
    lpTItemRcd := PTCLIENTITEM(m_BagItems.items[I]); 
 
    if (lpTItemRcd.MakeIndex = nItemIndex) then 
    begin 
      if lpTItemRcd.s.Name = pszMakeIndex then 
      begin 
        if TPlayerObject(m_pxPlayerObject).DropItemDown(lpTItemRcd, 2, False) 
          then 
        begin 
          m_BagItems.Delete(I); 
          TPlayerObject(m_pxPlayerObject).WeightChanged; 
          Result := True; 
          //Dispose(lpTItemRcd); 
          Exit; 
        end; 
      end; 
    end; 
  end; 
  { with m_lpTItemRcd.LockList do 
   begin 
     for I := 0 to Count - 1 do    // Iterate 
     begin 
       lpTItemRcd  := Items[I]; 
       if LeftBStr(pszMakeIndex, StrLen(@pszMakeIndex[1])) = LeftBStr(lpTItemRcd^.szMakeIndex, StrLen(@lpTItemRcd^.szMakeIndex[1])) then 
       begin 
         if TPlayerObject(m_pxPlayerObject).DropItemDown(lpTItemRcd, 2, False) then 
         begin 
           TPlayerObject(m_pxPlayerObject).UpdateItemToDB(lpTItemRcd, _ITEM_ACTION_THROW); 
 
           Delete(I); 
 
           TPlayerObject(m_pxPlayerObject).WeightChanged; 
           m_lpTItemRcd.UnlockList; 
           Result := True; 
           Exit; 
         end; 
       end; 
     end;    // for 
   end;    // with 
   m_lpTItemRcd.UnlockList; 
  } 
  Result := False; 
end; 
 
function TUserInfo.UserDropGenItem(nItemIndex: Integer; pszMakeIndex: string): 
  Boolean; 
var 
  I: Integer; 
  lpTItemRcd: PGENERALITEM_RCD; 
begin 
  if m_pxPlayerObject = nil then 
  begin 
    Result := False; 
    Exit; 
  end; 
 
  { with m_lpTGenItemRcd.LockList do 
   begin 
     for I := 0 to Count - 1 do    // Iterate 
     begin 
       lpTItemRcd  := Items[I]; 
       if LeftBStr(pszMakeIndex, StrLen(PChar(pszMakeIndex))) = LeftBStr(lpTItemRcd^.szMakeIndex, StrLen(@lpTItemRcd^.szMakeIndex[1])) then 
       begin 
         if TPlayerObject(m_pxPlayerObject).DropItemDown(PUSERITEM(lpTItemRcd), 2, False) then 
         begin 
           TPlayerObject(m_pxPlayerObject).UpdateItemToDB(PUSERITEM(lpTItemRcd), _ITEM_ACTION_THROW); 
 
           Delete(I); 
 
           TPlayerObject(m_pxPlayerObject).WeightChanged; 
           m_lpTItemRcd.UnlockList; 
           Result := True; 
           Exit; 
         end; 
       end; 
     end;    // for 
   end;    // with 
  } 
 //  m_lpTGenItemRcd.UnlockList; 
 
  Result := False; 
end; 
 
{添加金钱} 
function TUserInfo.IncGold(nGold: Integer): Boolean; 
begin 
  if (m_THumanRcd.dwGold + nGold) <= BAGGOLD then 
  begin 
    m_THumanRcd.dwGold := m_THumanRcd.dwGold + nGold; 
    Result := True; 
    Exit; 
  end; 
 
  Result := False; 
end; 
 
{减少金钱} 
function TUserInfo.DecGold(nGold: Integer): Boolean; 
begin 
  if (m_THumanRcd.dwGold - nGold) >= 0 then 
  begin 
    m_THumanRcd.dwGold := m_THumanRcd.dwGold - nGold; 
    FormMain.InsertLogMsg(IntToStr(m_THumanRcd.dwGold)); 
    Result := True; 
    Exit; 
  end; 
 
  Result := False; 
end; 
 
{通过魔法快捷键来获取魔法属性} 
function TUserInfo.GetMagicRcdByKey(nKey: Integer): PHUMANMAGIC_RCD; 
var 
  I: Integer; 
  lptUserMagicRcd: PHUMANMAGIC_RCD; 
  lptUserMagicRcdEx: PTClientMagic; 
   
begin 
  with m_lpTMagicRcd.LockList do 
  begin 
    for I := 0 to COunt - 1 do // Iterate 
    begin 
      lptUserMagicRcdEx := items[I]; 
 
      if lptUserMagicRcdEx <> nil then 
      begin 
        if StrToInt(lptUserMagicRcdEx^.key) = nKey then 
        begin 
          lptUserMagicRcd.btMagicID := lptUserMagicRcdEx^.Def.MagicID; 
          lptUserMagicRcd.btLevel := Char(lptUserMagicRcdEx^.Level); 
          lptUserMagicRcd.btUseKey := lptUserMagicRcdEx^.key; 
          lptUserMagicRcd.nCurrTrain := lptUserMagicRcdEx^.CurTrain; 
          Result := lptUserMagicRcd; 
          Exit; 
        end; 
      end; 
    end; // for 
  end; // with 
 
  Result := nil; 
end; 
 
{通过索引获取指定的魔法信息} 
function TUserInfo.GetMagicRcdByID(nID: Integer): PHUMANMAGIC_RCD; 
var 
  I: Integer; 
  lptUserMagicRcd: PHUMANMAGIC_RCD; 
  lptUserMagicRcdEx: PTClientMagic; 
begin 
  with m_lpTMagicRcd.LockList do 
  begin 
    for I := 0 to COunt - 1 do // Iterate 
    begin 
      lptUserMagicRcdEx := items[I]; 
 
      if lptUserMagicRcdEx <> nil then 
      begin 
        if lptUserMagicRcdEx^.Def.MagicID = nID then 
        begin 
          New(lptUserMagicRcd); 
          lptUserMagicRcd.btMagicID := lptUserMagicRcdEx^.Def.MagicID; 
          lptUserMagicRcd.btLevel := Char(lptUserMagicRcdEx^.Level); 
          lptUserMagicRcd.btUseKey := lptUserMagicRcdEx^.key; 
          lptUserMagicRcd.nCurrTrain := lptUserMagicRcdEx^.CurTrain; 
          Result := lptUserMagicRcd; 
          Exit; 
        end; 
      end; 
 
      {lptUserMagicRcd := items[I]; 
 
      if lptUserMagicRcd <> nil then 
      begin 
        if lptUserMagicRcd^.btMagicID = nID then 
        begin 
          Result := lptUserMagicRcd; 
          Exit; 
        end; 
      end;  } 
    end; // for 
  end; // with 
 
  Result := nil; 
end; 
 
function TUserInfo.CanUseBujuk: PGENERALITEM_RCD; 
var 
  nIndex: Integer; 
  lptItem: PGENERALITEM_RCD; 
begin 
  lptItem := GetUseGenItem(RightStr(string(@m_THumanRcd.szTakeItem[1]), 
    StrLen(@m_THumanRcd.szTakeItem[1]) - U_ARMRINGL)); 
 
  if lptItem <> nil then 
  begin 
    if lptItem^.szMakeIndex[1] = 'G' then 
    begin 
      nIndex := GetGenItemStdIdx(lptItem^.szMakeIndex); 
 
      if (g_pStdItemEtc[nIndex].wStdMode = 25) or (g_pStdItemEtc[nIndex].wStdMode 
        = 5) then 
      begin 
        Result := lptItem; 
        Exit; 
      end; 
    end; 
  end; 
 
  Result := nil; 
end; 
 
procedure TUserInfo.ProcessUserMessage(pszPacket: PChar; nLen: Integer); 
var 
  lpDefMsg: PDEFAULTMESSAGE_RCD; 
  nPos: Integer; 
  szWriteToFile, 
    szDecodeMsg: string; 
  dwWrite: LongWord; 
  Str: string; 
begin 
  SetLength(szDecodeMsg, 512); 
  lpDefMsg := PDEFAULTMESSAGE_RCD(pszPacket); 
  // FormMain.InsertLogMsg(Inttostr(lpDefMsg.wIdent)); 
 
  case lpDefMsg^.wIdent of 
    CM_HIT, 
      CM_POWERHIT, 
      CM_LONGHIT, 
      CM_WIDEHIT, 
      CM_HEAVYHIT, 
      CM_BIGHIT, 
      CM_FIREHIT: 
      begin 
        TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), 
          lpDefMsg^.wIdent, lpDefMsg^.wTag, LOWORD(lpDefMsg^.nRecog), 
          HIWORD(lpDefMsg^.nRecog), lpDefMsg^.wParam, ''); 
      end; 
    CM_TURN, 
      CM_WALK, 
      CM_RUN, 
      CM_SITDOWN, 
      CM_RIDE: 
      begin 
        TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), 
          lpDefMsg^.wIdent, lpDefMsg^.wTag, LOWORD(lpDefMsg^.nRecog), 
          HIWORD(lpDefMsg^.nRecog), lpDefMsg^.wParam, ''); 
      end; 
    CM_SPELL: 
      begin 
        TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), lpDefMsg^.wIdent, lpDefMsg^.wTag, 
          LOWORD(lpDefMsg^.nRecog), HIWORD(lpDefMsg^.nRecog), 
          MAKELONG(lpDefMsg^.wParam, lpDefMsg^.wSeries), ''); 
      end; 
    CM_USERBUYITEM: 
      begin 
        SetLength(Str, nLen - 13); 
        CopyMemory(@Str[1], @pszPacket[12], nLen - 13); 
        TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), lpDefMsg^.wIdent, lpDefMsg^.wParam, lpDefMsg^.wTag, 0, lpDefMsg^.nRecog, Str); 
 
      end; 
    CM_USERSELLITEM: 
      begin 
        SetLength(Str, nLen - 13); 
        CopyMemory(@Str[1], @pszPacket[12], nLen - 13); 
        TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), lpDefMsg^.wIdent, lpDefMsg^.wParam, lpDefMsg^.wTag, 0, lpDefMsg^.nRecog, Str); 
      end; 
    CM_CLICKNPC, CM_MERCHANTDLGSELECT, CM_USERGETDETAILITEM, 
      CM_MERCHANTQUERYSELLPRICE: 
      begin 
        SetLength(Str, nLen - 13); 
        CopyMemory(@Str[1], @pszPacket[12], nLen - 13); 
        TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), lpDefMsg^.wIdent, lpDefMsg^.wParam, 0, 0, lpDefMsg^.nRecog, Str); 
 
      end; 
    CM_TAKEONITEM, 
      CM_TAKEOFFITEM: 
      begin 
        SetLength(Str, nLen - 13); 
        CopyMemory(@Str[1], @pszPacket[12], nLen - 13); 
        TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), 
          lpDefMsg^.wIdent, lpDefMsg^.wSeries, lpDefMsg^.nRecog, lpDefMsg^.wParam, 
          lpDefMsg^.wTag, Str); 
      end; 
    CM_QUERYUSERNAME: 
      begin 
        TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), lpDefMsg^.wIdent, 0, lpDefMsg^.nRecog, lpDefMsg^.wParam, lpDefMsg^.wTag, ''); 
      end; 
    CM_EAT, 
      CM_DROPITEM: 
      begin 
        SetLength(Str, nLen - 13); 
        CopyMemory(@Str[1], @pszPacket[12], nLen - 13); 
        TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), lpDefMsg^.wIdent, lpDefMsg^.wSeries, lpDefMsg^.nRecog, 0, 0, Str); 
      end; 
    CM_PICKUP: 
      begin 
        TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), 
          lpDefMsg^.wIdent, lpDefMsg^.wSeries, lpDefMsg^.nRecog, lpDefMsg^.wTag, 
          lpDefMsg^.wParam, ''); 
      end; 
    CM_Say: 
      begin 
        SetLength(Str, nLen - 13); 
        CopyMemory(@Str[1], @pszPacket[12], nLen - 13); 
        TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), 
          lpDefMsg^.wIdent, lpDefMsg^.wSeries, lpDefMsg^.nRecog, lpDefMsg^.wParam, 
          lpDefMsg^.wTag, Str); 
 
      end; 
  else 
    begin 
      TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), 
        lpDefMsg^.wIdent, lpDefMsg^.wParam, lpDefMsg^.nRecog, lpDefMsg^.wTag, 0, 
        ''); 
    end; 
  end; // case 
end; 
 
procedure TUserInfo.Operate; 
begin 
  if (GetTickCount - TPlayerObject(m_pxPlayerObject).m_dwSearchTime) >= 
    TPlayerObject(m_pxPlayerObject).m_dwSearchTick then 
  begin 
    TPlayerObject(m_pxPlayerObject).m_dwSearchTime := GetTickCount; 
    TPlayerObject(m_pxPlayerObject).SearchViewRange; 
 
    if TPlayerObject(m_pxPlayerObject).m_btBright <> g_nMirDayTime then 
    begin 
      TPlayerObject(m_pxPlayerObject).m_btBright := g_nMirDayTime; 
      TPlayerObject(m_pxPlayerObject).AddProcess(TCharObject(m_pxPlayerObject), 
        RM_DAYCHANGING, 0, 0, 0, 0, ''); 
    end; 
  end; 
 
  TPlayerObject(m_pxPlayerObject).Operate; 
end; 
 
procedure TUserInfo.CloseUserHuman(step: Integer);       //退出指定的用户 
var 
  I: Integer; 
begin 
  if m_pxPlayerObject <> nil then 
  begin 
    m_THumanRcd.nCX := TPlayerObject(m_pxPlayerObject).m_nCurrX; 
    m_THumanRcd.nCY := TPlayerObject(m_pxPlayerObject).m_nCurrY; 
 
    if (TPlayerObject(m_pxPlayerObject).m_nDirection >= 0) and 
      (TPlayerObject(m_pxPlayerObject).m_nDirection <= 7) then 
    begin 
      m_THumanRcd.nDirection := TPlayerObject(m_pxPlayerObject).m_nDirection; 
    end 
    else 
    begin 
      m_THumanRcd.nDirection := 4; 
    end; 
 
    if TPlayerObject(m_pxPlayerObject).m_pMap <> nil then 
    begin 
      ZeroMemory(@m_THumanRcd.szMapName[1], StrLen(@m_THumanRcd.szMapName[1])); 
      CopyMemory(@m_THumanRcd.szMapName[1], 
        @TMirMap(TPlayerObject(m_pxPlayerObject).m_pMap).m_szMapName[1], 15); 
    end; 
 
    m_THumanRcd.szLevel := TPlayerObject(m_pxPlayerObject).m_Ability.Level; 
    m_THumanRcd.nExp := TPlayerObject(m_pxPlayerObject).m_WAbility.Exp; 
    m_THumanRcd.HP := TPlayerObject(m_pxPlayerObject).m_WAbility.HP; 
    m_THumanRcd.MAC := TPlayerObject(m_pxPlayerObject).m_WAbility.MAC; 
    m_THumanRcd.AC := TPlayerObject(m_pxPlayerObject).m_WAbility.AC; 
    // Save Player Information Data 
    SaveHumanToDB(step); 
  end; 
 
  if m_pxPlayerObject <> nil then 
  begin 
    //   TPlayerObject(m_pxPlayerObject).m_xVisibleObjectList.Clear; 
     //  TMirMap(TPlayerObject(m_pxPlayerObject).m_pMap).RemoveObject( TPlayerObject(m_pxPlayerObject).m_nCurrX,TPlayerObject(m_pxPlayerObject).m_nCurrY, 
     //                                        OS_MOVINGOBJECT, m_pxPlayerObject); 
 
    TPlayerObject(m_pxPlayerObject).m_fIsAlive := False; 
  end; 
 
 
 
  if m_lpTMagicRcd.LockList.COunt > 0 then 
  begin 
    m_lpTMagicRcd.Clear; 
  end; 
 
  if m_pxPlayerObject <> nil then 
  begin 
 
  end; 
  // if Step<>m_nCertification then 
   // CloseAccount(m_szUserID, m_nCertification); 
  m_bEmpty := True; 
end; 
 
procedure TUserInfo.SaveHumanToDB(step: Integer);          //保存人物信息到数据库 
var 
  Def: TDEFAULTMESSAGE_RCD; 
  tLoadHuman: TLOADHUMAN_RCD; 
  szEncodeMsg1: string; 
  szEncodeMsg2: string; 
  nPos: Integer; 
  I: Integer; 
  lpTItemRcd: PTCLIENTITEM; 
  lptUserMagicRcdEx: PHUMANMAGIC_RCD; 
  lptUserMagicRcd:PTClientMagic; 
begin 
  Def := MakeDefaultMsg(DB_SAVEHUMANRCD, step, 0, 0, 0); 
 
  //Fillchar(m_THumanRcd.szTakeItem, SizeOf(m_THumanRcd.szTakeItem), #0); 
  for I := 0 to 8 do               //保存身上装备 
  begin 
    if m_TakeItems[I].MakeIndex > 0 then 
    begin 
      m_THumanRcd.szTakeItem[I].Id := m_TakeItems[I].MakeIndex; 
      m_THumanRcd.szTakeItem[I].Stand := m_TakeItems[I].Dura; 
      m_THumanRcd.szTakeItem[I].MaxStand := m_TakeItems[I].DuraMax; 
      m_THumanRcd.szTakeItem[I].GoodId := 
        g_pStdItemHash.ValueOf(m_TakeItems[I].s.Name) + 1; 
    end; 
  end; 
  for I := 0 to m_BagItems.COunt - 1 do        //保存物品栏 
  begin 
    lpTItemRcd := PTCLIENTITEM(m_BagItems.items[I]); 
    if lpTItemRcd <> nil then 
    begin 
      m_THumanRcd.szTakeItem[I + 9].Id := lpTItemRcd^.MakeIndex; 
      m_THumanRcd.szTakeItem[I + 9].Stand := lpTItemRcd^.Dura; 
      m_THumanRcd.szTakeItem[I + 9].MaxStand := lpTItemRcd^.DuraMax; 
      m_THumanRcd.szTakeItem[I + 9].GoodId := 
        g_pStdItemHash.ValueOf(lpTItemRcd^.s.Name) + 1; 
    end; 
  end; 
 
  //Fillchar(m_THumanRcd.szTakeItem, SizeOf(m_THumanRcd.szTakeItem), #0); 
  for I := 0 to 3 do                        //保存四格 
  begin 
    if m_TakeItems[9 + I].MakeIndex > 0 then 
    begin 
      m_THumanRcd.KeepGoods[46 + I].Id := m_TakeItems[9 + i].MakeIndex; 
      m_THumanRcd.KeepGoods[46 + I].Stand := m_TakeItems[9 + i].Dura; 
      m_THumanRcd.KeepGoods[46 + I].MaxStand := m_TakeItems[9 + i].DuraMax; 
      m_THumanRcd.KeepGoods[46 + I].GoodId := 
        g_pStdItemHash.ValueOf(m_TakeItems[9 + i].s.Name) + 1; 
    end; 
  end; 
 
  with m_lpTMagicRcd.LockList do 
  begin 
    for i := 0 to COunt - 1 do 
    begin 
      lptUserMagicRcd := items[I]; 
      lptUserMagicRcdEx := items[i]; 
      m_THumanRcd.Magic12[i].Id := lptUserMagicRcd.Def.MagicID; 
      m_THumanRcd.Magic12[i].key := lptUserMagicRcdEx.btUseKey; 
      m_THumanRcd.Magic12[i].code := lptUserMagicRcd.Level; 
      m_THumanRcd.Magic12[i].no := lptUserMagicRcd.CurTrain; 
    end; 
  end; 
  m_lpTMagicRcd.UnlockList; 
 
  szEncodeMsg1 := EncodeMessage(Def);                                              //消息头 
  szEncodeMsg2 := EncodeString(m_szUserID) + '/' + EncodeString(m_szCharName) + 
    '/';                                                                          //帐号与角色名 
  szEncodeMsg2 := szEncodeMsg2 + EncodeBuffer(@m_THumanRcd, SizeOf(THUMAN_RCD));  //在加上角色的信息 
  SendRDBSocket(m_nCertification, @szEncodeMsg1[1], @szEncodeMsg2[1], 
    Length(szEncodeMsg2)); 
end; 
 
{关闭帐号} 
procedure TUserInfo.CloseAccount(pszName: string; nCertification: Integer); 
var 
  nLen: Integer; 
  szMsg: string; 
  pszPos: string; 
begin 
  SetLength(szMsg, 256); 
  nLen := StrLen(@pszName[1]); 
 
  szMsg := '(102/' + pszName + '/' + IntToStr(nCertification) + ')'; 
 
  FormMain.ClientSocketID.Socket.SendText(szMsg); 
end; 
 
procedure TUserInfo.DoClientCertification(pszPacket: string); 
var 
  pszDecodePacket, 
    szDecodePacket, 
    pszPos: string; 
  nPos, 
    nLen: Integer; 
begin 
  // SetLength(szDecodePacket, 64); 
 
  if m_btCurrentMode = USERMODE_NOTICE then 
  begin 
    nLen := StrLen(@pszPacket[1]); 
 
    nPos := pos('!', pszPacket); 
    if nPos > 0 then 
    begin 
      pszPos := Copy(pszPacket, 3, nLen - 3); 
      pszDecodePacket := DecodeString(pszPos); 
 
 
      if (pszDecodePacket[1] = '*') and (pszDecodePacket[2] = '*') then 
      begin 
        pszDecodePacket := RightBStr(pszDecodePacket, 
          StrLen(PChar(pszDecodePacket)) - 2); 
 
        nPos := pos('/', pszDecodePacket); 
        if nPos = 0 then 
        begin 
          Exit; 
        end; 
 
        m_szUserID := LeftBStr(pszDecodePacket, nPos - 1); 
 
        m_szCharName := GetMidBStr(pszDecodePacket, '/', '/'); 
 
        nPos := PosEx('/', pszDecodePacket, nPos + 1); 
 
        m_nCertification := StrToInt(GetMidBStrEx(pszDecodePacket, '/', '/', 
          nPos)); 
 
        nPos := PosEx('/', pszDecodePacket, nPos + 1); 
 
        m_nClientVersion := StrToInt(GetMidBStrEx(pszDecodePacket, '/', '/', 
          nPos)); 
 
        m_btCurrentMode := USERMODE_LOGIN; 
        LoadPlayer(self); 
        //        LoadHumanFromDB(m_nUserGateIndex,m_szUserID,m_szCharName,m_addr,  m_nCertification); 
      end; 
    end; 
  end; 
end; 
 
function TUserInfo.GetUserItem(nPosition: Integer): PUSERITEM; 
begin 
 
  Result := GetItem(nPosition); 
end; 
 
function TUserInfo.GetWeapon: PUSERITEM; 
begin 
  Result := GetUserItem(U_WEAPON); 
end; 
 
procedure TUserInfo.SetEmptyWeapon; 
begin 
  { ZeroMemory(@m_THumanRcd.szTakeItem[U_WEAPON][1], _MAKEITEMINDEX); 
   m_THumanRcd.szTakeItem[U_WEAPON][1] := '0'; 
  } 
end; 
 
procedure TUserInfo.SetEmptyDress; 
begin 
  //ZeroMemory(@m_THumanRcd.szTakeItem[U_DRESS][1], _MAKEITEMINDEX); 
 // m_THumanRcd.szTakeItem[U_DRESS][1]  := '0'; 
end; 
 
procedure TUserInfo.SetEmptyUseItem(I: Integer); 
begin 
  // ZeroMemory(@m_THumanRcd.szTakeItem[I][1], _MAKEITEMINDEX); 
  // m_THumanRcd.szTakeItem[I][1]        := '0'; 
end; 
 
function TUserInfo.GetDress: PUSERITEM; 
begin 
  Result := GetUserItem(U_DRESS); 
end; 
 
function TUserInfo.GetAccessory(nPosition: Integer): PUSERITEM; 
begin 
  Result := GetUserItem(nPosition); 
end; 
 
function TUserInfo.GetRightHand: PGENERALITEM_RCD; 
begin 
   //Result  := GetUseGenItem(String(m_THumanRcd.szTakeItem[U_RIGHTHAND])); 
end; 
 
function TUserInfo.GetGenderFeature: Byte; 
begin 
   Result  := m_THumanRcd.Sex; 
end; 
 
{获取头发外形} 
function TUserInfo.GetHairFeature: Byte; 
begin 
  Result := (m_THumanRcd.szHair * 2 + m_THumanRcd.Sex); 
end; 
 
function TUserInfo.GetHorseFeatureEx: Byte; 
begin 
  if m_lpTHorseRcd <> nil then 
  begin 
    Result := m_lpTHorseRcd^.btHorseType; 
  end 
  else 
  begin 
    Result := 0; 
  end; 
end; 
 
{获取角色当前的职业} 
function TUserInfo.GetJob: Integer; 
begin 
  Result := Integer(m_THumanRcd.btJob); 
end; 
 
{设置角色的职业} 
procedure TUserInfo.SetJob(nJob: Integer); 
begin 
  if (nJob >= 0) and (nJob < 3) then 
  begin 
    m_THumanRcd.btJob := Byte(nJob); 
  end; 
end; 
 
{获取攻击模式} 
function TUserInfo.GetAttackMode: Integer; 
begin 
  Result := 0; 
end; 
 
function TUserInfo.GetMagicID(MagicName: string): Integer; 
var 
  I: Integer; 
begin 
  Result := -1; 
  for I := 0 to High(g_pMagicInfo) do 
  begin 
    if g_pMagicInfo[I].Def.MagicName = MagicName then 
    begin 
      Result := g_pMagicInfo[I].Def.MagicID; 
      Exit; 
    end; 
  end; 
end; 
 
{判断包是不是満了} 
function TUserInfo.IsEnoughBag: Boolean; 
begin 
  if (m_TakeItemsCount + m_BagItems.COunt) >= USERITEMMAX then 
  begin 
    Result := False; 
  end 
  else 
  begin 
    Result := True; 
  end; 
  //  m_lpTItemRcd.UnlockList; 
   // m_lpTGenItemRcd.UnlockList; 
end; 
 
{获取当前金钱} 
function TUserInfo.GetGold: LongWord; 
begin 
  Result := m_THumanRcd.dwGold; 
end; 
 
{获取PK值} 
function TUserInfo.GetPK: Integer; 
begin 
  Result := m_THumanRcd.PK; 
end; 
 
{通过名获取物品名} 
function TUserInfo.GetItemByName(ItemName: string): PTCLIENTITEM; 
var 
  I: Integer; 
  cu: PTCLIENTITEM; 
begin 
  Result := nil; 
  for I := 0 to m_BagItems.COunt - 1 do 
  begin 
    cu := PTCLIENTITEM(m_BagItems.items[I]); 
    if cu <> nil then 
      if cu.s.Name = ItemName then 
      begin 
        Result := cu; 
        Exit; 
      end; 
  end; 
 
 
end; 
 
{通过获取物品名称来获取物品个数} 
function TUserInfo.GetItemNum(ItemName: string): Integer; 
var 
  I: Integer; 
  cu: PTCLIENTITEM; 
begin 
  Result := 0; 
  for I := 0 to m_BagItems.COunt - 1 do 
  begin 
    cu := PTCLIENTITEM(m_BagItems.items[I]); 
    if cu <> nil then 
      if cu.s.Name = ItemName then 
        Inc(Result); 
 
  end; 
 
 
end; 
 
{获取幸运值} 
function TUserInfo.GetLuck: Integer; 
begin 
  Result := TPlayerObject(m_pxPlayerObject).m_AddAbility.Luck; 
end; 
end.