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

外挂编程

开发平台:

Windows_Unix

  1. #!/usr/bin/env perl
  2. #########################################################################
  3. #  This software is open source, licensed under the GNU General Public
  4. #  License, version 2.
  5. #  Basically, this means that you're allowed to modify and distribute
  6. #  this software. However, if you distribute modified versions, you MUST
  7. #  also distribute the source code.
  8. #  See http://www.gnu.org/licenses/gpl.html for the full license.
  9. #########################################################################
  10. use strict;
  11. use FindBin qw($RealBin);
  12. use lib "$RealBin/src";
  13. use lib "$RealBin/src/deps";
  14. use Getopt::Long;
  15. use Data::YAML::Reader;
  16. my %options = (
  17. fields => 'fields',
  18. maps => 'map',
  19. logs => 'logs',
  20. );
  21. GetOptions(
  22. "fields=s" => $options{fields},
  23. "maps=s" => $options{maps},
  24. "logs=s" => $options{logs},
  25. "help" => $options{help}
  26. );
  27. if ($options{help}) {
  28. my $msg = <<EOF;
  29. mapview.pl [OPTIONS]
  30. Options:
  31.  --fields=path        Path to the folder containing .fld files.
  32.  --maps=path          Path to the folder containing map images.
  33.  --logs=path          Path to the folder containing log files.
  34. EOF
  35. $msg =~ s/^t*//gm;
  36. print $msg;
  37. exit 1;
  38. }
  39. my $app = new App;
  40. $app->MainLoop;
  41. package App;
  42. use Wx ':everything';
  43. use Wx::Event qw(EVT_TIMER);
  44. use base qw(Wx::App);
  45. use Interface::Wx::MapViewer;
  46. use Field;
  47. my $frame;
  48. my $sizer;
  49. my $mapview;
  50. my $status;
  51. my $field;
  52. my $bus;
  53. my $state;
  54. sub OnInit {
  55. my $self = shift;
  56. $frame = new Wx::Frame(undef, -1, 'Map viewer', wxDefaultPosition, wxDefaultSize,
  57. wxDEFAULT_FRAME_STYLE ^ wxMAXIMIZE_BOX);
  58. $frame->SetClientSize(75, 100);
  59. $frame->Show(1);
  60. $sizer = new Wx::BoxSizer(wxVERTICAL);
  61. $mapview = new Interface::Wx::MapViewer($frame);
  62. $mapview->setMapDir($options{maps});
  63. $mapview->onMouseMove->add(undef, &onMouseMove);
  64. $mapview->onMapChange->add(undef, &onMapChange);
  65. $sizer->Add($mapview, 1, wxGROW);
  66. $status = new Wx::StatusBar($frame, -1, wxST_SIZEGRIP);
  67. $status->SetFieldsCount(2);
  68. $status->SetStatusWidths(80, -1);
  69. $sizer->Add($status, 0, wxGROW);
  70. $frame->SetSizer($sizer);
  71. if ($ARGV[0] eq '') {
  72. $mapview->onClick->add(undef, &onClick);
  73. my $timer = new Wx::Timer($self, 5);
  74. EVT_TIMER($self, 5, &onTimer);
  75. $timer->Start(500);
  76. onTimer();
  77. $timer = new Wx::Timer($self, 6);
  78. EVT_TIMER($self, 6, &onBusTimer);
  79. $timer->Start(50);
  80. } else {
  81. $field = new Field(file => "$options{fields}/$ARGV[0].fld");
  82. $mapview->set($ARGV[0], $ARGV[1], $ARGV[2], $field);
  83. $mapview->update;
  84. }
  85. return 1;
  86. }
  87. sub onMouseMove {
  88. my (undef, undef, $args) = @_;
  89. my ($x, $y) = @{$args};
  90. $x = 0 if ($x < 0);
  91. $y = 0 if ($y < 0);
  92. $status->SetStatusText("Mouse over: $x, $y", 1);
  93. }
  94. sub onClick {
  95. my (undef, undef, $args) = @_;
  96. my ($x, $y) = @{$args};
  97. if ($state->{bus}{host} && (!$bus || $bus->serverHost() ne $state->{bus}{host} || $bus->serverPort() ne $state->{bus}{port})) {
  98. require Bus::Client;
  99. $bus = new Bus::Client(
  100. host => $state->{bus}{host},
  101. port => $state->{bus}{port},
  102. privateOnly => 1,
  103. userAgent => "Map Viewer"
  104. );
  105. }
  106. if ($bus) {
  107. $bus->send("MoveTo", {
  108. TO => $state->{bus}{clientID},
  109. field => $field->name(),
  110. x => $x,
  111. y => $y
  112. });
  113. }
  114. }
  115. sub onMapChange {
  116. $frame->SetTitle($field->name());
  117. $frame->Fit;
  118. }
  119. sub onTimer {
  120. my ($f, $reader);
  121. return unless (open($f, "<:utf8", "$options{logs}/state.yml"));
  122. $reader = new Data::YAML::Reader;
  123. eval {
  124. $state = $reader->read($f);
  125. };
  126. if ($@ || $state->{connectionState} ne 'in game') {
  127. return;
  128. }
  129. if (!$field || $state->{fieldName} ne $field->name()) {
  130. eval {
  131. $field = new Field(file => "$options{fields}/$state->{fieldBaseName}.fld",
  132. loadDistanceMap => 0);
  133. $field->{name} = $state->{fieldName};
  134. };
  135. }
  136. $mapview->set($state->{fieldBaseName}, $state->{x}, $state->{y}, $field);
  137. my (@npcs, @monsters, @players);
  138. foreach my $entry (@{$state->{actors}{NPC}}) {
  139. my %actor = (pos_to => $entry, pos => $entry);
  140. push @npcs, %actor;
  141. }
  142. foreach my $entry (@{$state->{actors}{Monster}}) {
  143. my %actor = (pos_to => $entry);
  144. push @monsters, %actor;
  145. }
  146. foreach my $entry (@{$state->{actors}{Player}}) {
  147. my %actor = (pos_to => $entry);
  148. push @players, %actor;
  149. }
  150. $mapview->setMonsters(@monsters);
  151. $mapview->setPlayers(@players);
  152. $mapview->setNPCs(@npcs);
  153. $mapview->update;
  154. $status->SetStatusText("$state->{x}, $state->{y}", 0);
  155. }
  156. sub onBusTimer {
  157. $bus->iterate() if ($bus);
  158. }