⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usrsoc.pas

📁 传奇服务端代码 DBServerSQL.rar 通讯部分
💻 PAS
📖 第 1 页 / 共 2 页
字号:
  sGateIPaddr: string;
begin
  sGateIPaddr := GetValidStr3(sIP, sUserIPaddr, ['/']);
  for I := 0 to GateInfo.UserList.Count - 1 do begin
    UserInfo := GateInfo.UserList.Items[I];
    if (UserInfo <> nil) and (UserInfo.sConnID = sID) then begin
      exit;
    end;
  end;
  New(UserInfo);
  UserInfo.sAccount := '';
  UserInfo.sUserIPaddr := sUserIPaddr;
  UserInfo.sGateIPaddr := sGateIPaddr;
  UserInfo.sConnID  := sID;
  UserInfo.nSessionID := 0;
  UserInfo.Socket   := GateInfo.Socket;
  UserInfo.s2C      := '';
  UserInfo.dwTick34 := GetTickCount();
  UserInfo.dwChrTick := GetTickCount();
  UserInfo.boChrSelected := False;
  UserInfo.boChrQueryed := False;
  UserInfo.nSelGateID := GateInfo.nGateID;
  GateInfo.UserList.Add(UserInfo);
end;
//004A30B8
procedure TFrmUserSoc.CloseUser(sID: string; var GateInfo: pTGateInfo);
var
  I: integer;
  UserInfo: pTUserInfo;
begin
  for I := 0 to GateInfo.UserList.Count - 1 do begin
    UserInfo := GateInfo.UserList.Items[I];
    if (UserInfo <> nil) and (UserInfo.sConnID = sID) then begin
      if not FrmIDSoc.GetGlobaSessionStatus(UserInfo.nSessionID) then begin
        FrmIDSoc.SendSocketMsg(SS_SOFTOUTSESSION, UserInfo.sAccount +
          '/' + IntToStr(UserInfo.nSessionID));
        FrmIDSoc.CloseSession(UserInfo.sAccount, UserInfo.nSessionID);
      end;
      Dispose(UserInfo);
      GateInfo.UserList.Delete(I);
      break;
    end;
  end;
end;

procedure TFrmUserSoc.DeCodeUserMsg(sData: string; var UserInfo: pTUserInfo);//004A48E0
var
  sDefMsg, s18: string;
  Msg: TDefaultMessage;
begin
  sDefMsg := Copy(sData, 1, DEFBLOCKSIZE);
  s18     := Copy(sData, DEFBLOCKSIZE + 1, Length(sData) - DEFBLOCKSIZE);
  Msg     := DecodeMessage(sDefMsg);
  case Msg.Ident of
    CM_QUERYCHR: begin
      if not UserInfo.boChrQueryed or ((GetTIckCount - UserInfo.dwChrTick) > 200) then
      begin
        UserInfo.dwChrTick := GetTickCount();
        if QueryChr(s18, UserInfo) then begin
          UserInfo.boChrQueryed := True;
        end;
      end else begin
        Inc(g_nQueryChrCount);
        OutMainMessage('[Hacker Attack] _QUERYCHR ' + UserInfo.sUserIPaddr);
      end;
    end;
    CM_NEWCHR: begin
      if (GetTickCount - UserInfo.dwChrTick) > 1000 then begin
        UserInfo.dwChrTick := GetTickCount();
        if (UserInfo.sAccount <> '') and FrmIDSoc.CheckSession(
          UserInfo.sAccount, UserInfo.sUserIPaddr, UserInfo.nSessionID) then begin
          NewChr(s18, UserInfo);
          UserInfo.boChrQueryed := False;
        end else begin
          OutOfConnect(UserInfo);
        end;
      end else begin
        Inc(nHackerNewChrCount);
        OutMainMessage('[Hacker Attack] _NEWCHR ' + UserInfo.sAccount +
          '/' + UserInfo.sUserIPaddr);
      end;
    end;
    CM_DELCHR: begin
      if (GetTickCount - UserInfo.dwChrTick) > 1000 then begin
        UserInfo.dwChrTick := GetTickCount();
        if (UserInfo.sAccount <> '') and FrmIDSoc.CheckSession(
          UserInfo.sAccount, UserInfo.sUserIPaddr, UserInfo.nSessionID) then begin
          DelChr(s18, UserInfo);
          UserInfo.boChrQueryed := False;
        end else begin
          OutOfConnect(UserInfo);
        end;
      end else begin
        Inc(nHackerDelChrCount);
        OutMainMessage('[Hacker Attack] _DELCHR ' + UserInfo.sAccount +
          '/' + UserInfo.sUserIPaddr);
      end;
    end;
    CM_SELCHR: begin
      if not UserInfo.boChrQueryed then begin
        if (UserInfo.sAccount <> '') and FrmIDSoc.CheckSession(
          UserInfo.sAccount, UserInfo.sUserIPaddr, UserInfo.nSessionID) then begin
          if SelectChr(s18, UserInfo) then begin
            UserInfo.boChrSelected := True;
          end;
        end else begin  //004A4D69
          OutOfConnect(UserInfo);
        end;
      end else begin//004A4D79
        Inc(nHackerSelChrCount);
        OutMainMessage('Double send _SELCHR ' + UserInfo.sAccount +
          '/' + UserInfo.sUserIPaddr);
      end;
    end;
    else begin
      Inc(n4ADC24);
    end;
  end;
end;
//004A3620
function TFrmUserSoc.QueryChr(sData: string; var UserInfo: pTUserInfo): boolean;
var
  sAccount: string;
  sSessionID: string;
  nSessionID: integer;
  nChrCount: integer;
  ChrList: TStringList;
  I:      integer;
  nIndex: integer;
  QueryChrRcd: TQueryChr;
  HumRecord: THumInfo;
  QuickID: pTQuickID;
  btSex:  byte;
  sChrName: string;
  sJob:   string;
  sHair:  string;
  sLevel: string;
  sBuf:    string;
begin
  Result     := False;
  sSessionID := GetValidStr3(DecodeString(sData), sAccount, ['/']);
  nSessionID := Str_ToInt(sSessionID, -2);
  UserInfo.nSessionID := nSessionID;
  nChrCount  := 0;

  if FrmIDSoc.CheckSession(sAccount, UserInfo.sUserIPaddr, nSessionID) then begin
    FrmIDSoc.SetGlobaSessionNoPlay(nSessionID);
    UserInfo.sAccount := sAccount;
    ChrList := TStringList.Create;
    try
      if HumChrDB.Open and (HumChrDB.FindByAccount(sAccount, ChrList) >= 0) then begin
        try
          if HumDataDB.Open then begin
            for I := 0 to ChrList.Count - 1 do begin
              QuickID := pTQuickID(ChrList.Objects[I]);
              //如果选择ID不对,则跳过
              if QuickID.nSelectID <> UserInfo.nSelGateID then Continue;

              if HumChrDB.GetBy(QuickID.nIndex, HumRecord) and (not HumRecord.boDeleted) then begin
                sChrName := QuickID.sChrName;
                nIndex   := HumDataDB.Index(sChrName);
                if (nIndex < 0) or (nChrCount >= g_nMaxCreateChar) then Continue;
                if HumDataDB.GetQryChar(nIndex, QueryChrRcd) >= 0 then begin
                  btSex  := QueryChrRcd.btGender;
                  sJob   := IntToStr(QueryChrRcd.btClass);
                  sHair  := IntToStr(QueryChrRcd.btHair);
                  sLevel := IntToStr(QueryChrRcd.btLevel);
                  if HumRecord.boSelected then sBuf := sBuf + '*';
                  sBuf := sBuf + sChrName + '/' + sJob + '/' + sHair +
                    '/' + sLevel + '/' + IntToStr(btSex) + '/';
                  Inc(nChrCount);
                end;
              end;
            end;
          end;
        finally
          HumDataDB.Close;
        end;
      end;
    finally
      HumChrDB.Close;
    end;
    ChrList.Free;
    SendUserSocket(UserInfo.Socket,
      UserInfo.sConnID,
      EncodeMessage(MakeDefaultMsg(SM_QUERYCHR, nChrCount, 0, 1, 0)) +
      EncodeString(sBuf));
    //*ChrName/sJob/sHair/sLevel/sSex/
  end else begin
    SendUserSocket(UserInfo.Socket,
      UserInfo.sConnID,
      EncodeMessage(MakeDefaultMsg(SM_QUERYCHR_FAIL, nChrCount, 0, 1, 0)));
    CloseUser(UserInfo.sConnID, CurGate);
  end;
end;

procedure TFrmUserSoc.OutOfConnect(const UserInfo: pTUserInfo);
//004A4844
var
  Msg:  TDefaultMessage;
  sMsg: string;
begin
  Msg  := MakeDefaultMsg(SM_OUTOFCONNECTION, 0, 0, 0, 0);
  sMsg := EncodeMessage(Msg);
  SendUserSocket(UserInfo.Socket, sMsg, UserInfo.sConnID);
end;

procedure TFrmUserSoc.DelChr(sData: string; var UserInfo: pTUserInfo);
//004A424C
var
  sChrName: string;
  boCheck:  boolean;
  Msg:      TDefaultMessage;
  sMsg:     string;
  nIndex:   integer;
  HumRecord: THumInfo;
begin
  g_CheckCode.dwThread0 := 1000300;
  sChrName := DecodeString(sData);
  boCheck  := False;
  g_CheckCode.dwThread0 := 1000301;
  try
    if HumChrDB.Open then begin
      nIndex := HumChrDB.Index(sChrName);
      if nIndex >= 0 then begin
        HumChrDB.Get(nIndex, HumRecord);
        if HumRecord.sAccount = UserInfo.sAccount then begin
          HumRecord.boDeleted := True;
          HumRecord.dModDate := Now();
          boCheck := HumChrDB.Update(nIndex, HumRecord);
        end;
      end;
    end;
  finally
    HumChrDB.Close;
  end;
  g_CheckCode.dwThread0 := 1000302;
  if boCheck then Msg := MakeDefaultMsg(SM_DELCHR_SUCCESS, 0, 0, 0, 0)
  else
    Msg := MakeDefaultMsg(SM_DELCHR_FAIL, 0, 0, 0, 0);

  sMsg := EncodeMessage(Msg);
  SendUserSocket(UserInfo.Socket, UserInfo.sConnID, sMsg);
  g_CheckCode.dwThread0 := 1000303;
end;

procedure TFrmUserSoc.NewChr(sData: string; var UserInfo: pTUserInfo);//004A3C08
var
  Data, sAccount, sChrName, sHair, sJob, sSex: string;
  nCode: integer;
  Msg:   TDefaultMessage;
  sMsg:  string;
  HumRecord: THumInfo;
  i:     integer;
begin
  nCode := -1;
  Data  := DecodeString(sData);
  Data  := GetValidStr3(Data, sAccount, ['/']);
  Data  := GetValidStr3(Data, sChrName, ['/']);
  Data  := GetValidStr3(Data, sHair, ['/']);
  Data  := GetValidStr3(Data, sJob, ['/']);
  Data  := GetValidStr3(Data, sSex, ['/']);
  if Trim(Data) <> '' then nCode := 0;
  sChrName := Trim(sChrName);
  if length(sChrName) < 3 then nCode := 0;
  if g_boEnglishNames and not IsEnglishStr(sChrName) then nCode := 0;
  if not CheckDenyChrName(sChrName) then nCode := 2;
  if not CheckChrName(sChrName) then nCode := 0;
  for I := 1 to length(sChrName) do begin
    if (sChrName[i] = #$A1) or (sChrName[i] = ' ') or (sChrName[i] = '/') or
      (sChrName[i] = '@') or (sChrName[i] = '?') or (sChrName[i] = '''') or
      (sChrName[i] = '"') or (sChrName[i] = '\') or (sChrName[i] = '.') or
      (sChrName[i] = ',') or (sChrName[i] = ':') or (sChrName[i] = ';') or
      (sChrName[i] = '`') or (sChrName[i] = '~') or (sChrName[i] = '!') or
      (sChrName[i] = '#') or (sChrName[i] = '$') or (sChrName[i] = '%') or
      (sChrName[i] = '^') or (sChrName[i] = '&') or (sChrName[i] = '*') or
      (sChrName[i] = '(') or (sChrName[i] = ')') or (sChrName[i] = '-') or
      (sChrName[i] = '_') or (sChrName[i] = '+') or (sChrName[i] = '=') or
      (sChrName[i] = '|') or (sChrName[i] = '[') or (sChrName[i] = '{') or
      (sChrName[i] = ']') or (sChrName[i] = '}') then nCode := 0;
  end;

  if nCode = -1 then begin
    try
      HumDataDB.Lock;
      if HumDataDB.Index(sChrName) >= 0 then nCode := 2;
    finally
      HumDataDB.UnLock;
    end;
    FillChar(HumRecord, SizeOf(THumInfo), #0);

    try
      if HumChrDB.Open then begin
        if HumChrDB.ChrCountOfAccount(sAccount) < g_nMaxCreateChar then begin
          HumRecord.sChrName     := sChrName;
          HumRecord.sAccount     := sAccount;
          HumRecord.boDeleted    := False;
          HumRecord.btCount      := 0;
          HumRecord.Header.sChrName  := sChrName;
          HumRecord.Header.nSelectID := UserInfo.nSelGateID;
          if HumRecord.sChrName <> '' then
            if not HumChrDB.Add(HumRecord) then nCode := 2;
        end else
          nCode := 3;
      end;
    finally
      HumChrDB.Close;
    end;

    if nCode = -1 then begin
      if NewChrData(sAccount, sChrName, Str_ToInt(sSex, 0), Str_ToInt(sJob, 0),
        Str_ToInt(sHair, 0)) then nCode := 1;
    end else begin
      FrmDBSrv.DelHum(sChrName);
      nCode := 4;
    end;
  end;
  if nCode = 1 then begin
    Msg := MakeDefaultMsg(SM_NEWCHR_SUCCESS, 0, 0, 0, 0);
  end else begin
    Msg := MakeDefaultMsg(SM_NEWCHR_FAIL, nCode, 0, 0, 0);
  end;
  sMsg := EncodeMessage(Msg);
  SendUserSocket(UserInfo.Socket, UserInfo.sConnID, sMsg);
end;
//004A440C
function TFrmUserSoc.SelectChr(sData: string; var UserInfo: pTUserInfo): boolean;
var
  sAccount: string;
  sChrName: string;
  ChrList: TStringList;
  HumRecord: THumInfo;
  I:      integer;
  nIndex: integer;
  nMapIndex: integer;
  QuickID: pTQuickID;
  sCurMap: string;
  boDataOK: boolean;
  sDefMsg: string;
  sRouteMsg: string;
  sRouteIP: string;
  nRoutePort: integer;
begin
  Result   := False;
  sChrName := GetValidStr3(DecodeString(sData), sAccount, ['/']);
  boDataOK := False;
  if UserInfo.sAccount = sAccount then begin
    try
      if HumChrDB.Open then begin
        ChrList := TStringList.Create;
        if HumChrDB.FindByAccount(sAccount, ChrList) >= 0 then begin
          for I := 0 to ChrList.Count - 1 do begin
            QuickID := pTQuickID(ChrList.Objects[i]);
            nIndex  := QuickID.nIndex;
            if HumChrDB.GetBy(nIndex, HumRecord) then begin
              if HumRecord.sChrName = sChrName then begin
                HumRecord.boSelected := True;
                HumChrDB.UpdateBy(nIndex, HumRecord);
              end else begin
                if HumRecord.boSelected then begin
                  HumRecord.boSelected := False;
                  HumChrDB.UpdateBy(nIndex, HumRecord);
                end;
              end;
            end;
          end;
        end;
        ChrList.Free;
      end;
    finally
      HumChrDB.Close;
    end;
    try
      if HumDataDB.Open then begin
        nIndex := HumDataDB.Index(sChrName);
        if nIndex >= 0 then begin
          sCurMap  := HumDataDB.GetUserCurMap(nIndex);
          boDataOK := True;
        end;
      end;
    finally
      HumDataDB.Close;
    end;
  end;
  if boDataOK then begin
    nMapIndex := GetMapIndex(sCurMap);
    sDefMsg   := EncodeMessage(MakeDefaultMsg(SM_STARTPLAY, 0, 0, 0, 0));
    sRouteIP  := GateRouteIP(CurGate.sGateaddr, nRoutePort);
    if g_boDynamicIPMode then sRouteIP := UserInfo.sGateIPaddr; //使用动态IP

    sRouteMsg := EncodeString(sRouteIP + '/' + IntToStr(nRoutePort + nMapIndex));
    SendUserSocket(UserInfo.Socket,
      UserInfo.sConnID,
      sDefMsg + sRouteMsg);
    FrmIDSoc.SetGlobaSessionPlay(UserInfo.nSessionID);
    Result := True;
  end else begin
    SendUserSocket(UserInfo.Socket,
      UserInfo.sConnID,
      EncodeMessage(MakeDefaultMsg(SM_STARTFAIL, 0, 0, 0, 0)));
  end;
end;

function TFrmUserSoc.GateRoutePort(sGateIP: string): integer;//004A2724
begin
  Result := 7200;
end;

function TFrmUserSoc.GateRouteIP(sGateIP: string; var nPort: integer): string;
  //0x004A258C

  function GetRoute(RouteInfo: pTRouteInfo; var nGatePort: integer): string;
  var
    nGateIndex: integer;
  begin
    nGateIndex := Random(RouteInfo.nGateCount);
    Result     := RouteInfo.sGameGateIP[nGateIndex];
    nGatePort  := RouteInfo.nGameGatePort[nGateIndex];
  end;

var
  I: integer;
  RouteInfo: pTRouteInfo;
begin
  nPort  := 0;
  Result := '';
  for I := Low(g_RouteInfo) to High(g_RouteInfo) do begin
    RouteInfo := @g_RouteInfo[I];
    if RouteInfo.sSelGateIP = sGateIP then begin
      Result := GetRoute(RouteInfo, nPort);
      break;
    end;
  end;
end;

function TFrmUserSoc.GetMapIndex(sMap: string): integer;//0x004A24D4
var
  i: integer;
begin
  Result := 0;
  for I := 0 to MapList.Count - 1 do begin
    if MapList.Strings[i] = sMap then begin
      Result := integer(MapList.Objects[i]);
      break;
    end;
  end;
end;

procedure TFrmUserSoc.SendUserSocket(Socket: TCustomWinSocket;
  sSessionID, sSendMsg: string);
//004A2E18
begin
  Socket.SendText('%' + sSessionID + '/#' + sSendMsg + '!$');
end;
//0045C2C0
function TFrmUserSoc.CheckDenyChrName(sChrName: string): boolean;
var
  i: integer;
begin
  Result := True;
  g_CheckCode.dwThread0 := 1000700;
  for I := 0 to DenyChrNameList.Count - 1 do begin
    g_CheckCode.dwThread0 := 1000701;
    if CompareText(sChrName, DenyChrNameList.Strings[i]) = 0 then begin
      g_CheckCode.dwThread0 := 1000702;
      Result := False;
      break;
    end;
  end;
  g_CheckCode.dwThread0 := 1000703;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -