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

外挂编程

开发平台:

Windows_Unix

  1. ############################################################
  2. # Poseidon query interface for OpenKore
  3. #
  4. # This program is free software; you can redistribute it and/or 
  5. # modify it under the terms of the GNU General Public License 
  6. # as published by the Free Software Foundation; either version 2 
  7. # of the License, or (at your option) any later version.
  8. #
  9. # Copyright (c) 2005-2006 OpenKore Development Team
  10. ############################################################
  11. ##
  12. # MODULE DESCRIPTION: Poseidon GameGuard query handler.
  13. #
  14. # Poseidon provides a simple way to respond to GameGuard queries.
  15. package Poseidon::Client;
  16. use strict;
  17. use IO::Socket::INET;
  18. use Globals qw(%config);
  19. use Log qw(error debug);
  20. use Bus::MessageParser;
  21. use Bus::Messages qw(serialize);
  22. use Utils qw(dataWaiting);
  23. use Plugins;
  24. use constant DEFAULT_POSEIDON_SERVER_PORT => 24390;
  25. use constant POSEIDON_SUPPORT_URL => 'http://www.openkore.com/aliases/poseidon.php';
  26. our $instance;
  27. # Poseidon::Client Poseidon::Client->new(String host, int port)
  28. #
  29. # Create a new Poseidon::Client object.
  30. sub _new {
  31. my ($class, $host, $port) = @_;
  32. my %self = (
  33. host => $host,
  34. port => $port
  35. );
  36. return bless %self, $class;
  37. }
  38. # IO::Socket::INET $PoseidonClient->_connect()
  39. #
  40. # Connect to the poseidon server.
  41. sub _connect {
  42. my ($self) = @_;
  43. my $socket = new IO::Socket::INET(
  44. PeerHost => $self->{host},
  45. PeerPort => $self->{port},
  46. Proto => 'tcp'
  47. );
  48. return $socket;
  49. }
  50. ##
  51. # void $PoseidonClient->query(Bytes packet)
  52. # packet: A GameGuard query packet.
  53. #
  54. # Send a GameGuard query packet to the Poseidon core.
  55. #
  56. # When an appropriate response packet has been determined,
  57. # it will be available through $PoseidonClient->getResult()
  58. sub query {
  59. my ($self, $packet) = @_;
  60. my $socket = $self->_connect();
  61. if (!$socket) {
  62. error "Your Ragnarok Online server uses GameGuard. In order " .
  63. "to support GameGuard, you must use the Poseidon " .
  64. "server. Please read " . POSEIDON_SUPPORT_URL .
  65. " for more information.n";
  66. return;
  67. }
  68. my (%args, $data);
  69. # Plugin hook to make it possible to add additional data piggy-backed
  70. # to the Poseidon request packet (auth information for example)
  71. Plugins::callHook('Poseidon/client_authenticate', {
  72. args => %args,
  73. });
  74. $args{packet} = $packet;
  75. $data = serialize("Poseidon Query", %args);
  76. $socket->send($data);
  77. $socket->flush();
  78. $self->{socket} = $socket;
  79. $self->{parser} = new Bus::MessageParser();
  80. }
  81. ##
  82. # Bytes $PoseidonClient->getResult()
  83. # Returns: the GameGuard query result, or undef if there is no result yet.
  84. # Ensures: if defined(result): !defined($self->getResult())
  85. #
  86. # Get the result for the last query.
  87. sub getResult {
  88. my ($self) = @_;
  89. if (!$self->{socket} || !$self->{socket}->connected
  90.  || !dataWaiting($self->{socket})) {
  91. return undef;
  92. }
  93. my ($buf, $ID, $args);
  94. $self->{socket}->recv($buf, 1024 * 32);
  95. if (!$buf) {
  96. # This shouldn't have happened.
  97. error "The Poseidon server closed the connection unexpectedly or could not respond " . 
  98. "to your request due to a server bandwidth issue. Please report this bug.n";
  99. $self->{socket} = undef;
  100. return undef;
  101. }
  102. $self->{parser}->add($buf);
  103. if ($args = $self->{parser}->readNext($ID)) {
  104. if ($ID ne "Poseidon Reply") {
  105. error "The Poseidon server sent a wrong reply ID ($ID). Please report this bug.n";
  106. $self->{socket} = undef;
  107. return undef;
  108. } else {
  109. $self->{socket} = undef;
  110. return $args->{packet};
  111. }
  112. } else {
  113. # We haven't gotten a full message yet.
  114. return undef;
  115. }
  116. }
  117. ##
  118. # Poseidon::Client Poseidon::Client::getInstance()
  119. #
  120. # Get the global Poseidon::Client instance.
  121. sub getInstance {
  122. if (!$instance) {
  123. $instance = Poseidon::Client->_new(
  124. $config{poseidonServer} || 'localhost',
  125. $config{poseidonPort} || DEFAULT_POSEIDON_SERVER_PORT);
  126. }
  127. return $instance;
  128. }
  129. 1;