From dd944416b7e8099844bf6c2a6b6a3f24dbaf4df0 Mon Sep 17 00:00:00 2001 From: Sergiotarxz Date: Sun, 18 Jun 2023 20:29:42 +0200 Subject: [PATCH] Adding log propagation and location change. --- Build.PL | 27 ++-- js-src/components/game.tsx | 8 +- js-src/components/upper-panel.tsx | 25 +++- js-src/input-packets.ts | 52 +++++++- js-src/output-packet.ts | 11 +- .../Controller/Websocket/InputPacket/Init.pm | 40 ++++-- .../Controller/Websocket/OutputPacket/Info.pm | 43 +++---- lib/LasTres/Location.pm | 116 +++++++++++++----- lib/LasTres/Redis.pm | 25 +++- lib/LasTres/Schema/Result/PJ.pm | 21 ++-- lib/LasTres/Schema/Result/PJLog.pm | 4 +- public/js/bundle.js | 18 ++- 12 files changed, 273 insertions(+), 117 deletions(-) diff --git a/Build.PL b/Build.PL index d0fc26d..ba063fe 100755 --- a/Build.PL +++ b/Build.PL @@ -9,19 +9,20 @@ my $build = Module::Build->new( dist_author => 'Sergio Iglesias ', dist_abstract => 'Juego de L3TDE.', requires => { - 'Mojolicious' => 0, - 'Moo' => 0, - 'Params::ValidationCompiler' => 0, - 'Types::Standard' => 0, - 'Crypt::URandom' => 0, - 'Crypt::Bcrypt' => 0, - 'DBIx::Class' => 0, - 'DBIx::Class::DeploymentHandler' => 0, - 'UUID::URandom' => 0, - 'Module::Pluggable' => 0, - 'Redis' => 0, - 'List::AllUtils' => 0, - 'DateTime::Format::Pg' => 0, + 'Mojolicious' => 0, + 'Moo' => 0, + 'Params::ValidationCompiler' => 0, + 'Types::Standard' => 0, + 'Crypt::URandom' => 0, + 'Crypt::Bcrypt' => 0, + 'DBIx::Class' => 0, + 'DBIx::Class::DeploymentHandler' => 0, + 'UUID::URandom' => 0, + 'Module::Pluggable' => 0, + 'Mojo::Redis' => 0, + 'List::AllUtils' => 0, + 'DateTime::Format::Pg' => 0, + 'DateTime::Format::ISO8601::Format' => 0, }, ); $build->create_build_script; diff --git a/js-src/components/game.tsx b/js-src/components/game.tsx index 6d9aba5..c9121c4 100644 --- a/js-src/components/game.tsx +++ b/js-src/components/game.tsx @@ -39,6 +39,7 @@ export default function Game (props: GameProps): JSX.Element { const [currentLocation, setCurrentLocation] = React.useState(null) const [connectedLocations, setConnectedLocations] = React.useState(null) const [logLines, setLogLines] = React.useState(null) + const [error, setError] = React.useState(null) if (websocket === null) { window.setTimeout(() => { const locationProtocol = window.location.protocol @@ -58,7 +59,9 @@ export default function Game (props: GameProps): JSX.Element { window.clearInterval(interval) }, 10000) } - const inputPackets = new InputPackets(setTeamPJs, setCurrentLocation, setConnectedLocations, setLogLines) + const inputPackets = new InputPackets(setTeamPJs, + setCurrentLocation, setConnectedLocations, + logLines, setLogLines, setError) webSocket.onmessage = (event) => { const packet = JSON.parse(event.data) inputPackets.handle(packet) @@ -74,7 +77,8 @@ export default function Game (props: GameProps): JSX.Element { + logLines={logLines} + websocket={websocket}/> ) diff --git a/js-src/components/upper-panel.tsx b/js-src/components/upper-panel.tsx index 498aea6..bb2c400 100644 --- a/js-src/components/upper-panel.tsx +++ b/js-src/components/upper-panel.tsx @@ -3,12 +3,14 @@ import type { Location } from '@lastres/location' import type { PJ } from '@lastres/pj' import type { LogLine } from '@lastres/log-line' import PJListItem from '@lastres/components/pj-list-item' +import MoveToPacket from '@lastres/output-packet/move-to' interface UpperPanelProps { connectedLocations: Location[] | null teamPJs: PJ[] | null currentLocation: Location | null logLines: LogLine[] | null + websocket: WebSocket | null } interface Style { @@ -21,6 +23,7 @@ export default function UpperPanel (props: UpperPanelProps): JSX.Element { const teamPJs = props.teamPJs const currentLocation = props.currentLocation const logLines = props.logLines + const websocket = props.websocket if (!(teamPJs !== null && currentLocation !== null && connectedLocations !== null)) { return ( <> @@ -28,14 +31,26 @@ export default function UpperPanel (props: UpperPanelProps): JSX.Element { ) } + + function onClickLocation (item: Location): void { + const moveToPacket = new MoveToPacket(item) + if (websocket !== null) { + moveToPacket.send(websocket) + } + } + function generateLog (): React.ReactNode { if (logLines === null || logLines.length < 1) { return ( <>No log ) } - return logLines.reverse().map((item, i) => { - return <> + return logLines.sort(function (a: LogLine, b: LogLine): number { + const aDate = Date.parse(a.date) + const bDate = Date.parse(b.date) + return aDate - bDate + }).map((item, i) => { + return {item.date} { item.content.map((item, i) => { const style: Style = {} @@ -48,7 +63,7 @@ export default function UpperPanel (props: UpperPanelProps): JSX.Element { return {item.text} }) }
- +
}) } return ( @@ -74,7 +89,9 @@ export default function UpperPanel (props: UpperPanelProps): JSX.Element { { connectedLocations.map((item, i) => { return
  • - {item.area.name}/{item.location.name} + { + onClickLocation(item) + }}>{item.area.name}/{item.location.name}
  • }) } diff --git a/js-src/input-packets.ts b/js-src/input-packets.ts index ced2015..e1a319a 100644 --- a/js-src/input-packets.ts +++ b/js-src/input-packets.ts @@ -4,30 +4,42 @@ import type InputPacket from '@lastres/input-packet' import type { LogLine } from '@lastres/log-line' import InputPacketInfo from '@lastres/input-packet/info' import InputPacketPong from '@lastres/input-packet/pong' + type SetTeamPJs = (set: PJ[] | null) => void type SetCurrentLocation = (set: Location | null) => void type SetConnectedLocations = (set: Location[] | null) => void type DispatchHash = Record -type SetLogLines = (set: LogLine[] | null) => void +type SetLogLinesCallback = (set: LogLine[] | null) => LogLine[] +type SetLogLines = (set: LogLine[] | SetLogLinesCallback | null) => void +type SetError = (set: string | null) => void + interface Packet { command: string data: any } +type LogHash = Record + export default class InputPackets { setTeamPJs: SetTeamPJs setCurrentLocation: SetCurrentLocation setConnectedLocations: SetConnectedLocations setLogLines: SetLogLines + logLines: LogLine[] | null cachedHash: DispatchHash | null = null cachedArray: InputPacket[] | null = null + setError: SetError constructor (setTeamPJs: SetTeamPJs, setCurrentLocation: SetCurrentLocation, setConnectedLocations: SetConnectedLocations, - setLogLines: SetLogLines) { + logLines: LogLine[] | null, + setLogLines: SetLogLines, + setError: SetError) { this.setTeamPJs = setTeamPJs this.setCurrentLocation = setCurrentLocation this.setConnectedLocations = setConnectedLocations + this.logLines = logLines this.setLogLines = setLogLines + this.setError = setError } handle (packet: Packet): void { @@ -42,10 +54,38 @@ export default class InputPackets { const infoPacket = new InputPacketInfo() const pongPacket = new InputPacketPong() infoPacket.onReceive((data) => { - this.setTeamPJs(data.team_pjs) - this.setConnectedLocations(data.location_data.connected_places) - this.setCurrentLocation(data.location_data.current) - this.setLogLines(data.set_log) + if (data.error !== undefined) { + this.setError(data.error) + return + } + if (data.team_pjs !== undefined) { + this.setTeamPJs(data.team_pjs) + } + if (data.location_data?.connected_places !== undefined) { + this.setConnectedLocations(data.location_data.connected_places) + } + if (data.location_data?.current !== undefined) { + this.setCurrentLocation(data.location_data.current) + } + if (data.set_log !== undefined) { + this.setLogLines(data.set_log) + } + if (data.append_log !== undefined) { + const logHash: LogHash = {} + this.setLogLines((logLines: LogLine[] | null): LogLine[] => { + if (logLines !== null) { + for (const item of logLines) { + logHash[item.uuid] = item + } + logHash[data.append_log.uuid] = data.append_log + const outputLog: LogLine[] = Object.keys(logHash).map((item, i): LogLine => { + return logHash[item] + }) + return outputLog + } + return [] + }) + } }) this.cachedArray = [infoPacket, pongPacket] } diff --git a/js-src/output-packet.ts b/js-src/output-packet.ts index d259dd5..e651a04 100644 --- a/js-src/output-packet.ts +++ b/js-src/output-packet.ts @@ -1,11 +1,10 @@ export default abstract class OutputPacket { - send(ws: WebSocket): void { - const data = this.data(); + send (ws: WebSocket): void { ws.send(JSON.stringify({ - command: this.command(), - data: this.data(), + command: this.command(), + data: this.data() })) } - abstract data(): any - abstract command(): string + abstract data (): any + abstract command (): string } diff --git a/lib/LasTres/Controller/Websocket/InputPacket/Init.pm b/lib/LasTres/Controller/Websocket/InputPacket/Init.pm index f0e6ed5..02d1f9f 100644 --- a/lib/LasTres/Controller/Websocket/InputPacket/Init.pm +++ b/lib/LasTres/Controller/Websocket/InputPacket/Init.pm @@ -11,7 +11,7 @@ use Data::Dumper; use Moo; -use JSON; +use JSON qw/to_json from_json/; use LasTres::Flags; use LasTres::Redis; @@ -29,22 +29,22 @@ sub identifier { sub handle ( $self, $ws, $session, $data ) { if ( ref $data ne 'HASH' ) { return $ws->send( - encode_json( { error => "Data should be a hashref." } ) ); + to_json( { error => "Data should be a hashref." } ) ); } my $pj_uuid = $data->{pj_uuid}; if ( !defined $pj_uuid ) { - return $ws->send( encode_json( { error => "No pj sent." } ) ); + return $ws->send( to_json( { error => "No pj sent." } ) ); } my @pjs = $result_set_pjs->search( { uuid => $pj_uuid } ); if ( !scalar @pjs ) { return $ws->send( - encode_json( { error => 'This pj does not exists' } ) ); + to_json( { error => 'This pj does not exists' } ) ); } my $pj = $pjs[0]; my $user = $session->{user}; if ( $pj->owner->uuid ne $user->uuid ) { return $ws->send( - encode_json( { error => 'You are not the owner of this pj.' } ) ); + to_json( { error => 'You are not the owner of this pj.' } ) ); } $session->{pj} = $pj; my $team = $pj->team; @@ -83,20 +83,34 @@ sub handle ( $self, $ws, $session, $data ) { clear => $JSON::true, ); $info_packet_to_send->send($ws); + require LasTres::Redis; + my $redis = LasTres::Redis->new; + say $redis->pj_subscription($pj); + $redis->subscribe($redis->pj_subscription($pj), my $save = sub($message, $topic, $topics) { + return $self->_on_redis_event($ws, $session, $message, $topic, $topics); + }); + $session->{redis} = $redis; +} + +sub _on_redis_event($self, $ws, $session, $message, $topic, $topics) { + say 'Receiving Redis event ' . $topic; + my $data = from_json($message); + my $pj = $session->{pj}; + if ($data->{command} eq 'append-log') { + my $info_packet_to_send = + LasTres::Controller::Websocket::OutputPacket::Info->new( + append_log => $data->{log} + ); + $info_packet_to_send->send($ws); + + } } sub _get_connected_places ( $self, $pj ) { my $team = $pj->team; my $location = $team->location; - my $connected_places = []; - if ( $location->can('connected_places') ) { - @$connected_places = ( @{ $team->location->connected_places } ); - } - @$connected_places = - ( @$connected_places, @{ $location->parent->children } ); - @$connected_places = - grep { $_->identifier ne $location->identifier } @$connected_places; + my $connected_places = $location->get_available_locations_to_move_to($pj); @$connected_places = map { $_->hash } @$connected_places; return $connected_places; } diff --git a/lib/LasTres/Controller/Websocket/OutputPacket/Info.pm b/lib/LasTres/Controller/Websocket/OutputPacket/Info.pm index 705998b..0e2638d 100644 --- a/lib/LasTres/Controller/Websocket/OutputPacket/Info.pm +++ b/lib/LasTres/Controller/Websocket/OutputPacket/Info.pm @@ -13,50 +13,45 @@ use Moo; with 'LasTres::Controller::Websocket::OutputPacket'; -has clear => ( - is => 'rw', -); +has clear => ( is => 'rw', ); -has team_pjs => ( - is => 'rw', -); +has team_pjs => ( is => 'rw', ); -has location_data => ( - is => 'rw', -); +has location_data => ( is => 'rw', ); -has set_log => ( - is => 'rw', -); +has set_log => ( is => 'rw', ); +has append_log => ( is => 'rw' ); sub identifier { return 'info'; } -sub data($self) { - my $clear = $self->clear; - my $team_pjs = $self->team_pjs; +sub data ($self) { + my $clear = $self->clear; + my $team_pjs = $self->team_pjs; my $location_data = $self->location_data; - my $set_log = $self->set_log; + my $set_log = $self->set_log; + my $append_log = $self->append_log; return { ( - (defined $clear) - ? (clear => $clear) + ( defined $clear ) ? ( clear => $clear ) : () ), ( - (defined $team_pjs) - ? (team_pjs => $team_pjs) + ( defined $team_pjs ) ? ( team_pjs => $team_pjs ) : () ), ( - (defined $location_data) - ? (location_data => $location_data) + ( defined $location_data ) ? ( location_data => $location_data ) : () ), ( - (defined $set_log) - ? (set_log => [map { $_->hash } @$set_log]) + ( defined $set_log ) ? ( set_log => [ map { $_->hash } @$set_log ] ) + : () + ), + ( + ( defined $append_log ) + ? ( append_log => $append_log ) : () ) }; diff --git a/lib/LasTres/Location.pm b/lib/LasTres/Location.pm index 9c82d15..01105c9 100644 --- a/lib/LasTres/Location.pm +++ b/lib/LasTres/Location.pm @@ -10,77 +10,131 @@ use feature 'signatures'; use LasTres::Planets; use Moo::Role; +use JSON qw/to_json/; + requires qw/identifier name description parent actions npcs/; my $planets = LasTres::Planets->new; -sub show_intro($self, $pj) { - $pj->append_log_line([ - { text => 'Estas en ' }, - { color => 'red', text => $self->parent->name }, - { text => '/' }, - { color => 'green', text => $self->name }, - ]); - $pj->append_log_line([ - { text => $pj->location->description }, - ]); +sub show_intro ( $self, $pj ) { + $pj->append_log_line( + [ + { text => 'Estas en ' }, + { color => 'red', text => $self->parent->name }, + { text => '/' }, + { color => 'green', text => $self->name }, + ] + ); + $pj->append_log_line( [ { text => $pj->location->description }, ] ); } -sub get($planet_id, $super_area_id, $area_id, $location_id) { +sub notify_arrival($self, $team) { + for my $pj ($team->members) { + $self->show_intro($pj); + } +} + +sub place_team($self, $team) { + $team->location($self); + $team->update; + $self->notify_arrival($team); +} + +sub to_json_array ($self) { + my $hash = $self->hash; + return to_json( + [ + $hash->{planet}{identifier}, $hash->{super_area}{identifier}, + $hash->{area}{identifier}, $hash->{location}{identifier} + ] + ); +} + +sub is_connected_by_move ( $self, $otherLocation, $pj = undef ) { + if ( !defined $otherLocation ) { + die '$otherLocation must be defined in is_connected.'; + } + my $json_array_other_location = $otherLocation->to_json_array; + if ( grep { $_->to_json_array eq $json_array_other_location } + @{ $self->get_available_locations_to_move_to($pj) } ) + { + return 1; + } + return 0; +} + +sub get_available_locations_to_move_to ( $self, $pj ) { + my $team = $pj->team; + my $location = $team->location; + + my $connected_places = []; + if ( $location->can('connected_places') ) { + @$connected_places = ( @{ $team->location->connected_places } ); + } + @$connected_places = + ( @$connected_places, @{ $location->parent->children } ); + @$connected_places = + grep { $_->identifier ne $location->identifier } @$connected_places; + return $connected_places; +} + +sub get ( $planet_id, $super_area_id, $area_id, $location_id ) { my $planet = $planets->hash->{$planet_id}; - if (!defined $planet) { + if ( !defined $planet ) { die "No such planet $planet_id."; } my $super_area = $planet->super_areas->{$super_area_id}; - if (!defined $super_area) { + if ( !defined $super_area ) { die "No such super_area $super_area_id in planet $planet_id."; } my $area = $super_area->areas->{$area_id}; - if (!defined $area) { - die "No such area $area_id in super_area $super_area_id in planet $planet_id."; + if ( !defined $area ) { + die +"No such area $area_id in super_area $super_area_id in planet $planet_id."; } my $location = $area->locations->{$location_id}; - if (!defined $location) { - die "No such location $location_id in area $area_id in super_area $super_area_id in planet $planet_id."; - + if ( !defined $location ) { + die +"No such location $location_id in area $area_id in super_area $super_area_id in planet $planet_id."; + } return $location; } -sub hash($self) { +sub hash ($self) { my $location = $self; - if (!Moo::Role::does_role($location, 'LasTres::Location')) { + if ( !Moo::Role::does_role( $location, 'LasTres::Location' ) ) { die "$location does not implement LasTres::Location."; } my $area = $location->parent; - if (!Moo::Role::does_role($area, 'LasTres::Area')) { - die "$area does not implement LasTres::Area."; + if ( !Moo::Role::does_role( $area, 'LasTres::Area' ) ) { + die "$area does not implement LasTres::Area."; } my $super_area = $area->parent; - if (!Moo::Role::does_role($super_area, 'LasTres::SuperArea')) { - die "$super_area does not implement LasTres::SuperArea."; + if ( !Moo::Role::does_role( $super_area, 'LasTres::SuperArea' ) ) { + die "$super_area does not implement LasTres::SuperArea."; } my $planet = $super_area->parent; - if (!Moo::Role::does_role($planet, 'LasTres::Planet')) { - die "$planet does not implement LasTres::Planet."; + if ( !Moo::Role::does_role( $planet, 'LasTres::Planet' ) ) { + die "$planet does not implement LasTres::Planet."; } return { planet => { - name => $planet->name, + name => $planet->name, identifier => $planet->identifier, }, super_area => { - name => $super_area->name, + name => $super_area->name, identifier => $super_area->identifier, }, area => { - name => $area->name, + name => $area->name, identifier => $area->identifier, }, location => { - name => $location->name, + name => $location->name, identifier => $location->identifier, }, - } + }; } 1; diff --git a/lib/LasTres/Redis.pm b/lib/LasTres/Redis.pm index 9664dfc..eb423e0 100644 --- a/lib/LasTres/Redis.pm +++ b/lib/LasTres/Redis.pm @@ -7,24 +7,37 @@ use warnings; use feature 'signatures'; -use parent 'Redis'; +use parent 'Mojo::Redis'; use LasTres::Schema; our $VERSION = $LasTres::Schema::VERSION; - { - my $cached_redis; sub new { + my $self; my $class = shift; - if (!defined $cached_redis) { - $cached_redis = $class->SUPER::new(@_); + if (!defined $self) { + $self = $class->SUPER::new(@_); } - return $cached_redis; + return $self; } } sub prefix { return "LasTres::Redis::$VERSION"; } + +sub subscribe($self, $topic, $callback) { + $self->pubsub->listen($topic, sub($self, $message, $topic) { + $callback->($message, $topic, [$topic]); + }); +} + +sub publish($self, $topic, $message) { + $self->pubsub->notify($topic, $message); +} + +sub pj_subscription($class, $pj) { + return prefix() . '::Subscriptions::PJ::' . $pj->uuid; +} 1; diff --git a/lib/LasTres/Schema/Result/PJ.pm b/lib/LasTres/Schema/Result/PJ.pm index b4609bb..8ddabf1 100644 --- a/lib/LasTres/Schema/Result/PJ.pm +++ b/lib/LasTres/Schema/Result/PJ.pm @@ -251,6 +251,8 @@ sub last_50_log ($self) { sub append_log_line ( $self, $content ) { require LasTres::Schema; + require LasTres::Redis; + my $redis = LasTres::Redis->new; if ( ref $content ne 'ARRAY' ) { die 'Bad log content, not a arrayref.'; } @@ -281,13 +283,19 @@ sub append_log_line ( $self, $content ) { } } my $uuid = create_uuid_string; - LasTres::Schema->Schema->resultset('PJLog') + my $log = + LasTres::Schema->Schema->resultset('PJLog') ->new( - { uuid => $uuid, owner => $self->uuid, content => to_json($content) } ) - ->insert; + { uuid => $uuid, owner => $self->uuid, content => to_json($content) } ); + $log->insert; + $log = $log->get_from_storage; + + say 'Sending redis event '. $redis->pj_subscription($self); + $redis->publish( $redis->pj_subscription($self), + to_json( { command => 'append-log', log => $log->hash } ) ); } -sub location($self) { +sub location ($self) { return $self->team->location; } @@ -299,12 +307,12 @@ sub set_flag ( $self, $name ) { require LasTres::Schema; my $schema = LasTres::Schema->Schema; my $result_set_flags = $schema->resultset('PJFlag'); - my $flag = $result_set_flags->new({name => $name, owner => $self->uuid}) + my $flag = $result_set_flags->new( { name => $name, owner => $self->uuid } ) ->update_or_insert; } sub get_flag ( $self, $name ) { - my @flags = $self->flags->search({name => $name}); + my @flags = $self->flags->search( { name => $name } ); if ( scalar @flags ) { return 1; } @@ -314,5 +322,4 @@ sub get_flag ( $self, $name ) { sub clear_flag ( $self, $name ) { $self->flags->search( name => $name )->delete; } - 1; diff --git a/lib/LasTres/Schema/Result/PJLog.pm b/lib/LasTres/Schema/Result/PJLog.pm index 51bd3ab..5f75f14 100644 --- a/lib/LasTres/Schema/Result/PJLog.pm +++ b/lib/LasTres/Schema/Result/PJLog.pm @@ -11,6 +11,7 @@ use parent 'DBIx::Class::Core'; use Data::Dumper; use JSON qw/from_json/; +use DateTime::Format::ISO8601::Format; use Moo; @@ -48,10 +49,11 @@ __PACKAGE__->set_primary_key('uuid'); __PACKAGE__->belongs_to( 'owner', 'LasTres::Schema::Result::PJ' ); sub hash ($self) { + my $iso_formatter = DateTime::Format::ISO8601::Format->new(second_precision => 3); return { uuid => $self->uuid, content => $self->content, - date => $self->date, + date => $iso_formatter->format_datetime($self->date) }; } diff --git a/public/js/bundle.js b/public/js/bundle.js index f2d561f..201fce8 100644 --- a/public/js/bundle.js +++ b/public/js/bundle.js @@ -96,7 +96,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ Game)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _lastres_components_upper_panel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lastres/components/upper-panel */ \"./js-src/components/upper-panel.tsx\");\n/* harmony import */ var _lastres_components_bottom_panel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @lastres/components/bottom-panel */ \"./js-src/components/bottom-panel.tsx\");\n/* harmony import */ var _lastres_components_pj_selection_menu__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @lastres/components/pj-selection-menu */ \"./js-src/components/pj-selection-menu.tsx\");\n/* harmony import */ var _lastres_output_packet_init__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @lastres/output-packet/init */ \"./js-src/output-packet/init.ts\");\n/* harmony import */ var _lastres_output_packet_ping__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @lastres/output-packet/ping */ \"./js-src/output-packet/ping.ts\");\n/* harmony import */ var _lastres_input_packets__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @lastres/input-packets */ \"./js-src/input-packets.ts\");\n\n\n\n\n\n\n\nfunction Game(props) {\n const selectedPJ = props.selectedPJ;\n if (selectedPJ === null) {\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_pj_selection_menu__WEBPACK_IMPORTED_MODULE_3__[\"default\"], { setSelectedPJ: props.setSelectedPJ, userWantsToCreatePJ: props.userWantsToCreatePJ, setUserWantsToCreatePJ: props.setUserWantsToCreatePJ, error: props.error, setError: props.setError })));\n }\n const [websocket, setWebsocket] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [teamPJs, setTeamPJs] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [currentLocation, setCurrentLocation] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [connectedLocations, setConnectedLocations] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [logLines, setLogLines] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n if (websocket === null) {\n window.setTimeout(() => {\n const locationProtocol = window.location.protocol;\n if (locationProtocol == null) {\n return;\n }\n const protocol = locationProtocol.match(/https:/) != null ? 'wss' : 'ws';\n const webSocket = new WebSocket(`${protocol}://${window.location.host}/ws`);\n webSocket.onopen = () => {\n new _lastres_output_packet_init__WEBPACK_IMPORTED_MODULE_4__[\"default\"](selectedPJ.uuid).send(webSocket);\n let interval = 0;\n interval = window.setInterval(() => {\n if (webSocket.readyState === WebSocket.OPEN) {\n new _lastres_output_packet_ping__WEBPACK_IMPORTED_MODULE_5__[\"default\"]().send(webSocket);\n return;\n }\n window.clearInterval(interval);\n }, 10000);\n };\n const inputPackets = new _lastres_input_packets__WEBPACK_IMPORTED_MODULE_6__[\"default\"](setTeamPJs, setCurrentLocation, setConnectedLocations, setLogLines);\n webSocket.onmessage = (event) => {\n const packet = JSON.parse(event.data);\n inputPackets.handle(packet);\n };\n webSocket.onerror = (event) => {\n console.log(event);\n };\n setWebsocket(webSocket);\n }, 1);\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_upper_panel__WEBPACK_IMPORTED_MODULE_1__[\"default\"], { teamPJs: teamPJs, currentLocation: currentLocation, connectedLocations: connectedLocations, logLines: logLines }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_bottom_panel__WEBPACK_IMPORTED_MODULE_2__[\"default\"], null)));\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/components/game.tsx?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ Game)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _lastres_components_upper_panel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lastres/components/upper-panel */ \"./js-src/components/upper-panel.tsx\");\n/* harmony import */ var _lastres_components_bottom_panel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @lastres/components/bottom-panel */ \"./js-src/components/bottom-panel.tsx\");\n/* harmony import */ var _lastres_components_pj_selection_menu__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @lastres/components/pj-selection-menu */ \"./js-src/components/pj-selection-menu.tsx\");\n/* harmony import */ var _lastres_output_packet_init__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @lastres/output-packet/init */ \"./js-src/output-packet/init.ts\");\n/* harmony import */ var _lastres_output_packet_ping__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @lastres/output-packet/ping */ \"./js-src/output-packet/ping.ts\");\n/* harmony import */ var _lastres_input_packets__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @lastres/input-packets */ \"./js-src/input-packets.ts\");\n\n\n\n\n\n\n\nfunction Game(props) {\n const selectedPJ = props.selectedPJ;\n if (selectedPJ === null) {\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_pj_selection_menu__WEBPACK_IMPORTED_MODULE_3__[\"default\"], { setSelectedPJ: props.setSelectedPJ, userWantsToCreatePJ: props.userWantsToCreatePJ, setUserWantsToCreatePJ: props.setUserWantsToCreatePJ, error: props.error, setError: props.setError })));\n }\n const [websocket, setWebsocket] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [teamPJs, setTeamPJs] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [currentLocation, setCurrentLocation] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [connectedLocations, setConnectedLocations] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [logLines, setLogLines] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [error, setError] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n if (websocket === null) {\n window.setTimeout(() => {\n const locationProtocol = window.location.protocol;\n if (locationProtocol == null) {\n return;\n }\n const protocol = locationProtocol.match(/https:/) != null ? 'wss' : 'ws';\n const webSocket = new WebSocket(`${protocol}://${window.location.host}/ws`);\n webSocket.onopen = () => {\n new _lastres_output_packet_init__WEBPACK_IMPORTED_MODULE_4__[\"default\"](selectedPJ.uuid).send(webSocket);\n let interval = 0;\n interval = window.setInterval(() => {\n if (webSocket.readyState === WebSocket.OPEN) {\n new _lastres_output_packet_ping__WEBPACK_IMPORTED_MODULE_5__[\"default\"]().send(webSocket);\n return;\n }\n window.clearInterval(interval);\n }, 10000);\n };\n const inputPackets = new _lastres_input_packets__WEBPACK_IMPORTED_MODULE_6__[\"default\"](setTeamPJs, setCurrentLocation, setConnectedLocations, logLines, setLogLines, setError);\n webSocket.onmessage = (event) => {\n const packet = JSON.parse(event.data);\n inputPackets.handle(packet);\n };\n webSocket.onerror = (event) => {\n console.log(event);\n };\n setWebsocket(webSocket);\n }, 1);\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_upper_panel__WEBPACK_IMPORTED_MODULE_1__[\"default\"], { teamPJs: teamPJs, currentLocation: currentLocation, connectedLocations: connectedLocations, logLines: logLines, websocket: websocket }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_bottom_panel__WEBPACK_IMPORTED_MODULE_2__[\"default\"], null)));\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/components/game.tsx?"); /***/ }), @@ -186,7 +186,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \*******************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ UpperPanel)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _lastres_components_pj_list_item__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lastres/components/pj-list-item */ \"./js-src/components/pj-list-item.tsx\");\n\n\nfunction UpperPanel(props) {\n const connectedLocations = props.connectedLocations;\n const teamPJs = props.teamPJs;\n const currentLocation = props.currentLocation;\n const logLines = props.logLines;\n if (!(teamPJs !== null && currentLocation !== null && connectedLocations !== null)) {\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, \"Esperando datos...\")));\n }\n function generateLog() {\n if (logLines === null || logLines.length < 1) {\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, \"No log\"));\n }\n return logLines.reverse().map((item, i) => {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"b\", null, item.date),\n \" \",\n item.content.map((item, i) => {\n const style = {};\n if (item.color !== undefined) {\n style.color = item.color;\n }\n if (item.background !== undefined) {\n style.background = item.background;\n }\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", { key: i, style: style }, item.text);\n }),\n \" \",\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null));\n });\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"presentation\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"presentation-item\" }, teamPJs.map((item, i) => {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_pj_list_item__WEBPACK_IMPORTED_MODULE_1__[\"default\"], { key: i, pj: item });\n })),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"presentation-item\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"code\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"pre\", null, generateLog()))),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"presentation-item\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null,\n \"Est\\u00E1s en \",\n currentLocation.area.name,\n \"/\",\n currentLocation.location.name,\n \".\"),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, \"Puedes ir a:\"),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"ul\", null, connectedLocations.map((item, i) => {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"li\", { key: i },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { href: \"#\" },\n item.area.name,\n \"/\",\n item.location.name));\n })))));\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/components/upper-panel.tsx?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ UpperPanel)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _lastres_components_pj_list_item__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lastres/components/pj-list-item */ \"./js-src/components/pj-list-item.tsx\");\n/* harmony import */ var _lastres_output_packet_move_to__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @lastres/output-packet/move-to */ \"./js-src/output-packet/move-to.ts\");\n\n\n\nfunction UpperPanel(props) {\n const connectedLocations = props.connectedLocations;\n const teamPJs = props.teamPJs;\n const currentLocation = props.currentLocation;\n const logLines = props.logLines;\n const websocket = props.websocket;\n if (!(teamPJs !== null && currentLocation !== null && connectedLocations !== null)) {\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, \"Esperando datos...\")));\n }\n function onClickLocation(item) {\n const moveToPacket = new _lastres_output_packet_move_to__WEBPACK_IMPORTED_MODULE_2__[\"default\"](item);\n if (websocket !== null) {\n moveToPacket.send(websocket);\n }\n }\n function generateLog() {\n if (logLines === null || logLines.length < 1) {\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, \"No log\"));\n }\n return logLines.sort(function (a, b) {\n const aDate = Date.parse(a.date);\n const bDate = Date.parse(b.date);\n return aDate - bDate;\n }).map((item, i) => {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", { key: i },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"b\", null, item.date),\n \" \",\n item.content.map((item, i) => {\n const style = {};\n if (item.color !== undefined) {\n style.color = item.color;\n }\n if (item.background !== undefined) {\n style.background = item.background;\n }\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", { key: i, style: style }, item.text);\n }),\n \" \",\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"br\", null));\n });\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"presentation\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"presentation-item\" }, teamPJs.map((item, i) => {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_pj_list_item__WEBPACK_IMPORTED_MODULE_1__[\"default\"], { key: i, pj: item });\n })),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"presentation-item\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"code\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"pre\", null, generateLog()))),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"presentation-item\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null,\n \"Est\\u00E1s en \",\n currentLocation.area.name,\n \"/\",\n currentLocation.location.name,\n \".\"),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, \"Puedes ir a:\"),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"ul\", null, connectedLocations.map((item, i) => {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"li\", { key: i },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { href: \"#\", onClick: () => {\n onClickLocation(item);\n } },\n item.area.name,\n \"/\",\n item.location.name));\n })))));\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/components/upper-panel.tsx?"); /***/ }), @@ -236,7 +236,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \*********************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ InputPackets)\n/* harmony export */ });\n/* harmony import */ var _lastres_input_packet_info__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @lastres/input-packet/info */ \"./js-src/input-packet/info.ts\");\n/* harmony import */ var _lastres_input_packet_pong__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lastres/input-packet/pong */ \"./js-src/input-packet/pong.ts\");\n\n\nclass InputPackets {\n constructor(setTeamPJs, setCurrentLocation, setConnectedLocations, setLogLines) {\n this.cachedHash = null;\n this.cachedArray = null;\n this.setTeamPJs = setTeamPJs;\n this.setCurrentLocation = setCurrentLocation;\n this.setConnectedLocations = setConnectedLocations;\n this.setLogLines = setLogLines;\n }\n handle(packet) {\n const hash = this.hashAvailablePackets();\n const identifier = packet.command;\n const inputPacket = hash[identifier];\n inputPacket.recv(packet);\n }\n listAvailablePackets() {\n if (this.cachedArray === null) {\n const infoPacket = new _lastres_input_packet_info__WEBPACK_IMPORTED_MODULE_0__[\"default\"]();\n const pongPacket = new _lastres_input_packet_pong__WEBPACK_IMPORTED_MODULE_1__[\"default\"]();\n infoPacket.onReceive((data) => {\n this.setTeamPJs(data.team_pjs);\n this.setConnectedLocations(data.location_data.connected_places);\n this.setCurrentLocation(data.location_data.current);\n this.setLogLines(data.set_log);\n });\n this.cachedArray = [infoPacket, pongPacket];\n }\n return this.cachedArray;\n }\n hashAvailablePackets() {\n if (this.cachedHash === null) {\n this.cachedHash = {};\n for (const inputPacket of this.listAvailablePackets()) {\n this.cachedHash[inputPacket.identifier()] = inputPacket;\n }\n }\n return this.cachedHash;\n }\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/input-packets.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ InputPackets)\n/* harmony export */ });\n/* harmony import */ var _lastres_input_packet_info__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @lastres/input-packet/info */ \"./js-src/input-packet/info.ts\");\n/* harmony import */ var _lastres_input_packet_pong__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lastres/input-packet/pong */ \"./js-src/input-packet/pong.ts\");\n\n\nclass InputPackets {\n constructor(setTeamPJs, setCurrentLocation, setConnectedLocations, logLines, setLogLines, setError) {\n this.cachedHash = null;\n this.cachedArray = null;\n this.setTeamPJs = setTeamPJs;\n this.setCurrentLocation = setCurrentLocation;\n this.setConnectedLocations = setConnectedLocations;\n this.logLines = logLines;\n this.setLogLines = setLogLines;\n this.setError = setError;\n }\n handle(packet) {\n const hash = this.hashAvailablePackets();\n const identifier = packet.command;\n const inputPacket = hash[identifier];\n inputPacket.recv(packet);\n }\n listAvailablePackets() {\n if (this.cachedArray === null) {\n const infoPacket = new _lastres_input_packet_info__WEBPACK_IMPORTED_MODULE_0__[\"default\"]();\n const pongPacket = new _lastres_input_packet_pong__WEBPACK_IMPORTED_MODULE_1__[\"default\"]();\n infoPacket.onReceive((data) => {\n if (data.error !== undefined) {\n this.setError(data.error);\n return;\n }\n if (data.team_pjs !== undefined) {\n this.setTeamPJs(data.team_pjs);\n }\n if (data.location_data?.connected_places !== undefined) {\n this.setConnectedLocations(data.location_data.connected_places);\n }\n if (data.location_data?.current !== undefined) {\n this.setCurrentLocation(data.location_data.current);\n }\n if (data.set_log !== undefined) {\n this.setLogLines(data.set_log);\n }\n if (data.append_log !== undefined) {\n const logHash = {};\n this.setLogLines((logLines) => {\n if (logLines !== null) {\n for (const item of logLines) {\n logHash[item.uuid] = item;\n }\n logHash[data.append_log.uuid] = data.append_log;\n const outputLog = Object.keys(logHash).map((item, i) => {\n return logHash[item];\n });\n return outputLog;\n }\n return [];\n });\n }\n });\n this.cachedArray = [infoPacket, pongPacket];\n }\n return this.cachedArray;\n }\n hashAvailablePackets() {\n if (this.cachedHash === null) {\n this.cachedHash = {};\n for (const inputPacket of this.listAvailablePackets()) {\n this.cachedHash[inputPacket.identifier()] = inputPacket;\n }\n }\n return this.cachedHash;\n }\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/input-packets.ts?"); /***/ }), @@ -256,7 +256,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \*********************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ OutputPacket)\n/* harmony export */ });\nclass OutputPacket {\n send(ws) {\n const data = this.data();\n ws.send(JSON.stringify({\n command: this.command(),\n data: this.data(),\n }));\n }\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/output-packet.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ OutputPacket)\n/* harmony export */ });\nclass OutputPacket {\n send(ws) {\n ws.send(JSON.stringify({\n command: this.command(),\n data: this.data()\n }));\n }\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/output-packet.ts?"); /***/ }), @@ -270,6 +270,16 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ }), +/***/ "./js-src/output-packet/move-to.ts": +/*!*****************************************!*\ + !*** ./js-src/output-packet/move-to.ts ***! + \*****************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ MoveToPacket)\n/* harmony export */ });\n/* harmony import */ var _lastres_output_packet__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @lastres/output-packet */ \"./js-src/output-packet.ts\");\n\nclass MoveToPacket extends _lastres_output_packet__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\n constructor(location) {\n super();\n this.location = location;\n }\n command() {\n return 'move_to';\n }\n data() {\n return {\n location: this.location.location.identifier,\n area: this.location.area.identifier,\n super_area: this.location.super_area.identifier,\n planet: this.location.planet.identifier\n };\n }\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/output-packet/move-to.ts?"); + +/***/ }), + /***/ "./js-src/output-packet/ping.ts": /*!**************************************!*\ !*** ./js-src/output-packet/ping.ts ***!