AccountServer.pm
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:3k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. # A basic implementation of an RO account server.
  2. # One should implement the abstract methods to implement a fully functional RO account server.
  3. package Base::Ragnarok::AccountServer;
  4. use strict;
  5. use Exception::Class qw(
  6. Base::Ragnarok::AccountServer::AccountNotFound
  7. Base::Ragnarok::AccountServer::PasswordIncorrect
  8. Base::Ragnarok::AccountServer::AccountBanned
  9. );
  10. use Modules 'register';
  11. use Base::RagnarokServer;
  12. use base qw(Base::RagnarokServer);
  13. use Socket qw(inet_aton);
  14. use Utils::Exceptions;
  15. use enum qw(LOGIN_SUCCESS ACCOUNT_NOT_FOUND PASSWORD_INCORRECT ACCOUNT_BANNED);
  16. sub new {
  17. my $class = shift;
  18. my %options = @_;
  19. my $self = $class->SUPER::new(
  20. $options{host},
  21. $options{port},
  22. $options{serverType},
  23. $options{rpackets}
  24. );
  25. $self->{sessionStore} = $options{sessionStore};
  26. $self->{charServers} = [$options{charServer}];
  27. return $self;
  28. }
  29. ##
  30. # abstract int $Base_Ragnarok_AccountServer->login(Hash* session, String username, String password)
  31. #
  32. # This method is called whenever an RO client tries to login. It authenticates the
  33. # specified user with the specified password, and fills the session hash with necessary
  34. # session information upon success.
  35. #
  36. # Upon calling this method, the session hash already contains two members:
  37. # `l
  38. # - sessionID - A unique 32-bit integer for this login session.
  39. # - sessionID2 - Another unique 32-bit integer for this login session.
  40. # `l`
  41. #
  42. # If the username is incorrect, then ACCOUNT_NOT_FOUND is returned.
  43. # If the password is incorrect, then PASSWORD_INCORRECT is returned.
  44. # If the account is banned, then ACCOUNT_BANNED is returned.
  45. #
  46. # Otherwise (that is, login is successful) LOGIN_SUCCESS is returned. The session
  47. # information hash must be filled with at least the following members:
  48. # `l
  49. # - accountID - The account's ID, as a raw byte string.
  50. # - sex - Specifies the gender of this account. 0 means female, 1 means male.
  51. # `l`
  52. sub login {
  53. die "This is an abstract method and has not been implemented.";
  54. }
  55. sub process_0064 {
  56. my ($self, $client, $message) = @_;
  57. my ($version, $username, $password, $master_version) = unpack("x2 V Z24 Z24 C1", $message);
  58. my $sessionID = $self->{sessionStore}->generateSessionID();
  59. my %session = (
  60. sessionID => $sessionID,
  61. sessionID2 => $sessionID
  62. );
  63. my $result = $self->login(%session, $username, $password);
  64. if ($result == LOGIN_SUCCESS) {
  65. my $output = pack('V a4 V x30 C',
  66. $session{sessionID}, # session ID
  67. $session{accountID}, # account ID
  68. $session{sessionID2}, # session ID 2
  69. $session{sex} # gender
  70. );
  71. $self->{sessionStore}->add(%session);
  72. $session{state} = 'About to select character';
  73. # Show list of character servers.
  74. foreach my $charServer (@{$self->{charServers}}) {
  75. my $host = inet_aton($charServer->getHost());
  76. $output .= pack('a4 v Z20 v C1 x3',
  77. $host, # host
  78. $charServer->getPort(), # port
  79. $charServer->getName(), # character server name
  80. $charServer->getPlayersCount(), # number of players
  81. 5 # display (5 = "don't show number of players)
  82. );
  83. }
  84. $client->send(pack('C2 v', 0x69, 0x00, length($output) + 4) . $output);
  85. $client->close();
  86. } elsif ($result == ACCOUNT_NOT_FOUND) {
  87. $client->send(pack('C*', 0x6A, 0x00, 0));
  88. $client->close();
  89. } elsif ($result == PASSWORD_INCORRECT) {
  90. $client->send(pack('C*', 0x6A, 0x00, 1));
  91. $client->close();
  92. } elsif ($result == ACCOUNT_BANNED) {
  93. $client->send(pack('C*', 0x6A, 0x00, 4));
  94. $client->close();
  95. } else {
  96. die "Unexpected result $result.";
  97. }
  98. }
  99. sub unhandledMessage {
  100. my ($self, $client) = @_;
  101. $client->close();
  102. }
  103. 1;