Rename DynmapPlayer to LiveAtlasPlayer, rename some fields, add uuid field

This commit is contained in:
James Lyne 2021-07-24 02:27:25 +01:00
parent 44b3a7e276
commit 1d27e05f7c
14 changed files with 80 additions and 82 deletions

View File

@ -44,11 +44,10 @@ import LinkControl from "@/components/map/control/LinkControl.vue";
import ChatControl from "@/components/map/control/ChatControl.vue";
import LogoControl from "@/components/map/control/LogoControl.vue";
import {MutationTypes} from "@/store/mutation-types";
import {DynmapPlayer} from "@/dynmap";
import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap";
import {LoadingControl} from "@/leaflet/control/LoadingControl";
import MapContextMenu from "@/components/map/MapContextMenu.vue";
import {Coordinate} from "@/index";
import {Coordinate, LiveAtlasPlayer} from "@/index";
export default defineComponent({
components: {
@ -277,7 +276,7 @@ export default defineComponent({
this.leaflet.getContainer().focus();
}
},
updateFollow(player: DynmapPlayer, newFollow: boolean) {
updateFollow(player: LiveAtlasPlayer, newFollow: boolean) {
const store = useStore(),
followMapName = store.state.configuration.followMap,
currentWorld = store.state.currentWorld;
@ -285,17 +284,17 @@ export default defineComponent({
let targetWorld = null;
if(!this.leaflet) {
console.warn(`Cannot follow ${player.account}. Map not yet initialized.`);
console.warn(`Cannot follow ${player.name}. Map not yet initialized.`);
return;
}
if(player.hidden) {
console.warn(`Cannot follow ${player.account}. Player is hidden from the map.`);
console.warn(`Cannot follow ${player.name}. Player is hidden from the map.`);
return;
}
if(!player.location.world) {
console.warn(`Cannot follow ${player.account}. Player isn't in a known world.`);
console.warn(`Cannot follow ${player.name}. Player isn't in a known world.`);
return;
}
@ -306,7 +305,7 @@ export default defineComponent({
}
if (!targetWorld) {
console.warn(`Cannot follow ${player.account}. Player isn't in a known world.`);
console.warn(`Cannot follow ${player.name}. Player isn't in a known world.`);
return;
}

View File

@ -17,15 +17,16 @@
<script lang="ts">
import {defineComponent, computed, ref, onMounted, onUnmounted} from "@vue/runtime-core";
import {LayerGroup} from 'leaflet';
import {DynmapChat, DynmapPlayer} from "@/dynmap";
import {DynmapChat} from "@/dynmap";
import {useStore} from "@/store";
import {PlayerMarker} from "@/leaflet/marker/PlayerMarker";
import {Popup} from "leaflet";
import {LiveAtlasPlayer} from "@/index";
export default defineComponent({
props: {
player: {
type: Object as () => DynmapPlayer,
type: Object as () => LiveAtlasPlayer,
required: true
},
layerGroup: {
@ -96,7 +97,7 @@ export default defineComponent({
break;
}
if(message.type === 'chat' && message.playerAccount === props.player.account) {
if(message.type === 'chat' && message.playerAccount === props.player.name) {
messages.push(message);
}
}

View File

@ -21,7 +21,7 @@
<div :class="{'following__target': true, 'following__target--hidden': target.hidden}">
<img width="32" height="32" class="target__icon" :src="image" alt="" />
<span class="target__info">
<span class="target__name" v-html="target.name"></span>
<span class="target__name" v-html="target.displayName"></span>
<span class="target__status" v-show="target.hidden">{{ messageHidden }}</span>
</span>
<button class="target__unfollow" type="button" :title="messageUnfollowTitle"
@ -31,25 +31,25 @@
</template>
<script lang="ts">
import {DynmapPlayer} from "@/dynmap";
import {useStore} from "@/store";
import {MutationTypes} from "@/store/mutation-types";
import {computed, defineComponent, onMounted, ref, watch} from "@vue/runtime-core";
import {getMinecraftHead} from '@/util';
import defaultImage from '@/assets/images/player_face.png';
import {LiveAtlasPlayer} from "@/index";
export default defineComponent({
name: 'FollowTarget',
props: {
target: {
type: Object as () => DynmapPlayer,
type: Object as () => LiveAtlasPlayer,
required: true
}
},
setup(props) {
const store = useStore(),
image = ref(defaultImage),
account = ref(props.target.account),
account = ref(props.target.name),
heading = computed(() => store.state.messages.followingHeading),
messageUnfollow = computed(() => store.state.messages.followingUnfollow),
@ -124,4 +124,4 @@ export default defineComponent({
margin-top: 0;
}
}
</style>
</style>

View File

@ -62,7 +62,7 @@ export default defineComponent({
const query = searchQuery.value.toLowerCase();
return query ? store.state.sortedPlayers.filter(p => {
return p.account.toLowerCase().indexOf(query) > -1;
return p.name.toLowerCase().indexOf(query) > -1;
}) : store.state.sortedPlayers;
}),
maxPlayers = computed(() => store.state.configuration.maxPlayers),

View File

@ -15,29 +15,29 @@
-->
<template>
<input :id="`player-${player.account}`" type="radio" name="player" v-bind:value="player.account" v-model="followTarget"
<input :id="`player-${player.name}`" type="radio" name="player" v-bind:value="player.name" v-model="followTarget"
@click.prevent="onInputClick" />
<label :for="`player-${player.account}`"
<label :for="`player-${player.name}`"
:class="{'player': true, 'player--hidden' : !!player.hidden, 'player--other-world': otherWorld}" :title="title"
@click.prevent="onLabelClick">
<img width="16" height="16" class="player__icon" :src="image" alt="" aria-hidden="true" />
<span class="player__name" v-html="player.name"></span>
<span class="player__name" v-html="player.displayName"></span>
</label>
</template>
<script lang="ts">
import {defineComponent, computed, ref, onMounted} from 'vue';
import {DynmapPlayer} from "@/dynmap";
import {useStore} from "@/store";
import {MutationTypes} from "@/store/mutation-types";
import {getMinecraftHead} from '@/util';
import defaultImage from '@/assets/images/player_face.png';
import {LiveAtlasPlayer} from "@/index";
export default defineComponent({
name: 'PlayerListItem',
props: {
player: {
type: Object as () => DynmapPlayer,
type: Object as () => LiveAtlasPlayer,
required: true
}
},
@ -59,7 +59,7 @@ export default defineComponent({
}
}),
followTarget = computed(() => store.state.followTarget ? store.state.followTarget.account : undefined),
followTarget = computed(() => store.state.followTarget ? store.state.followTarget.name : undefined),
pan = () => {
if(!props.player.hidden) {

14
src/dynmap.d.ts vendored
View File

@ -20,7 +20,7 @@ import {LogoControlOptions} from "@/leaflet/control/LogoControl";
import {ClockControlOptions} from "@/leaflet/control/ClockControl";
import {
Coordinate,
LiveAtlasLocation,
LiveAtlasPlayer,
LiveAtlasServerMessageConfig,
LiveAtlasWorldDefinition,
LiveAtlasWorldState
@ -110,21 +110,11 @@ interface DynmapUpdateResponse {
worldState: LiveAtlasWorldState;
configHash: number;
playerCount: number;
players: Set<DynmapPlayer>;
players: Set<LiveAtlasPlayer>;
updates: DynmapUpdates;
timestamp: number;
}
interface DynmapPlayer {
account: string;
armor: number;
health: number;
name: string;
sort: number;
hidden: boolean;
location: LiveAtlasLocation;
}
interface DynmapMarkerSet {
id: string,
label: string;

15
src/index.d.ts vendored
View File

@ -1,5 +1,5 @@
import {State} from "@/store";
import {DynmapPlayer, DynmapUrlConfig} from "@/dynmap";
import {DynmapUrlConfig} from "@/dynmap";
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
declare module "*.png" {
@ -108,7 +108,18 @@ export type LiveAtlasUIElement = 'layers' | 'chat' | 'players' | 'maps' | 'setti
export type LiveAtlasSidebarSection = 'servers' | 'players' | 'maps';
export type LiveAtlasDimension = 'overworld' | 'nether' | 'end';
interface LiveAtlasSortedPlayers extends Array<DynmapPlayer> {
interface LiveAtlasPlayer {
name: string;
displayName: string;
uuid?: string;
armor: number;
health: number;
sort: number;
hidden: boolean;
location: LiveAtlasLocation;
}
interface LiveAtlasSortedPlayers extends Array<LiveAtlasPlayer> {
dirty?: boolean;
}

View File

@ -18,9 +18,9 @@
*/
import {MarkerOptions, DivIcon, DomUtil} from 'leaflet';
import {DynmapPlayer} from "@/dynmap";
import {getMinecraftHead} from '@/util';
import playerImage from '@/assets/images/player_face.png';
import {LiveAtlasPlayer} from "@/index";
const noSkinImage: HTMLImageElement = document.createElement('img');
noSkinImage.height = 16;
@ -49,7 +49,7 @@ export interface PlayerIconOptions extends MarkerOptions {
}
export class PlayerIcon extends DivIcon {
private readonly _player: DynmapPlayer;
private readonly _player: LiveAtlasPlayer;
private _container?: HTMLDivElement;
private _playerImage?: HTMLImageElement;
private _playerInfo?: HTMLSpanElement;
@ -65,7 +65,7 @@ export class PlayerIcon extends DivIcon {
// @ts-ignore
options: PlayerIconOptions;
constructor(player: DynmapPlayer, options: PlayerIconOptions) {
constructor(player: LiveAtlasPlayer, options: PlayerIconOptions) {
super(options);
this._player = player;
}
@ -87,7 +87,7 @@ export class PlayerIcon extends DivIcon {
this._playerName = document.createElement('span');
this._playerName.className = 'player__name';
this._playerName.innerHTML = this._currentName = player.name;
this._playerName.innerHTML = this._currentName = player.displayName;
if (this.options.showSkinFace) {
let size;
@ -151,8 +151,8 @@ export class PlayerIcon extends DivIcon {
return;
}
if(this._player!.name !== this._currentName) {
this._playerName!.innerHTML = this._currentName = this._player!.name;
if(this._player!.displayName !== this._currentName) {
this._playerName!.innerHTML = this._currentName = this._player!.displayName;
}
if(this.options.showHealth) {

View File

@ -15,8 +15,8 @@
*/
import {LatLng, MarkerOptions, Marker, Util} from 'leaflet';
import {DynmapPlayer} from "@/dynmap";
import {PlayerIcon} from "@/leaflet/icon/PlayerIcon";
import {LiveAtlasPlayer} from "@/index";
export interface PlayerMarkerOptions extends MarkerOptions {
smallFace: boolean,
@ -26,9 +26,9 @@ export interface PlayerMarkerOptions extends MarkerOptions {
}
export class PlayerMarker extends Marker {
private _player: DynmapPlayer;
private _player: LiveAtlasPlayer;
constructor(player: DynmapPlayer, options: PlayerMarkerOptions) {
constructor(player: LiveAtlasPlayer, options: PlayerMarkerOptions) {
super(new LatLng(0, 0), options);
this._player = player;
options.draggable = false;

View File

@ -16,7 +16,7 @@
import {
LiveAtlasDimension,
LiveAtlasDynmapServerDefinition, LiveAtlasServerDefinition,
LiveAtlasDynmapServerDefinition, LiveAtlasPlayer, LiveAtlasServerDefinition,
LiveAtlasServerMessageConfig,
LiveAtlasWorldDefinition
} from "@/index";
@ -25,8 +25,7 @@ import {
DynmapCircle,
DynmapComponentConfig,
DynmapLine,
DynmapMarker, DynmapMarkerSet, DynmapMarkerSetUpdates, DynmapPlayer,
DynmapServerConfig, DynmapTileUpdate, DynmapUpdate, DynmapUpdateResponse,
DynmapMarker, DynmapMarkerSet, DynmapMarkerSetUpdates, DynmapServerConfig, DynmapTileUpdate, DynmapUpdate, DynmapUpdateResponse,
DynmapUpdates
} from "@/dynmap";
import {useStore} from "@/store";
@ -698,16 +697,16 @@ export default class DynmapMapProvider extends MapProvider {
this.updateAbort = new AbortController();
const response = await DynmapMapProvider.fetchJSON(url, this.updateAbort.signal);
const players: Set<DynmapPlayer> = new Set();
const players: Set<LiveAtlasPlayer> = new Set();
(response.players || []).forEach((player: any) => {
const world = player.world && player.world !== '-some-other-bogus-world-' ? player.world : undefined;
players.add({
account: player.account || "",
name: player.account || "",
displayName: player.name || "",
health: player.health || 0,
armor: player.armor || 0,
name: player.name || "",
sort: player.sort || 0,
hidden: !world,
location: {

View File

@ -23,9 +23,9 @@ import {
DynmapAreaUpdate, DynmapCircleUpdate, DynmapLineUpdate,
DynmapMarkerSet,
DynmapMarkerUpdate,
DynmapPlayer, DynmapTileUpdate,
DynmapTileUpdate,
} from "@/dynmap";
import {LiveAtlasWorldDefinition} from "@/index";
import {LiveAtlasPlayer, LiveAtlasWorldDefinition} from "@/index";
type AugmentedActionContext = {
commit<K extends keyof Mutations>(
@ -46,7 +46,7 @@ export interface Actions {
):Promise<void>
[ActionTypes.SET_PLAYERS](
{commit}: AugmentedActionContext,
payload: Set<DynmapPlayer>
payload: Set<LiveAtlasPlayer>
):Promise<Map<string, DynmapMarkerSet>>
[ActionTypes.POP_MARKER_UPDATES](
{commit}: AugmentedActionContext,
@ -156,17 +156,17 @@ export const actions: ActionTree<State, State> & Actions = {
state.currentMapProvider!.stopUpdates();
},
[ActionTypes.SET_PLAYERS]({commit, state}, players: Set<DynmapPlayer>) {
[ActionTypes.SET_PLAYERS]({commit, state}, players: Set<LiveAtlasPlayer>) {
const keep: Set<string> = new Set();
for(const player of players) {
keep.add(player.account);
keep.add(player.name);
}
//Remove any players that aren't in the set
commit(MutationTypes.SYNC_PLAYERS, keep);
const processQueue = (players: Set<DynmapPlayer>, resolve: Function) => {
const processQueue = (players: Set<LiveAtlasPlayer>, resolve: Function) => {
commit(MutationTypes.SET_PLAYERS_ASYNC, players);
if(!players.size) {

View File

@ -24,7 +24,6 @@ import {
DynmapLine, DynmapMarker,
DynmapMarkerSet,
DynmapMarkerSetUpdates,
DynmapPlayer,
DynmapServerConfig, DynmapTileUpdate,
DynmapChat
} from "@/dynmap";
@ -38,7 +37,7 @@ import {
LiveAtlasParsedUrl,
LiveAtlasGlobalConfig,
LiveAtlasGlobalMessageConfig,
LiveAtlasServerMessageConfig, LiveAtlasDynmapServerDefinition
LiveAtlasServerMessageConfig, LiveAtlasDynmapServerDefinition, LiveAtlasPlayer
} from "@/index";
import DynmapMapProvider from "@/providers/DynmapMapProvider";
@ -70,7 +69,7 @@ export type Mutations<S = State> = {
[MutationTypes.POP_LINE_UPDATES](state: S, payload: {markerSet: string, amount: number}): void
[MutationTypes.POP_TILE_UPDATES](state: S, amount: number): void
[MutationTypes.SET_PLAYERS_ASYNC](state: S, players: Set<DynmapPlayer>): Set<DynmapPlayer>
[MutationTypes.SET_PLAYERS_ASYNC](state: S, players: Set<LiveAtlasPlayer>): Set<LiveAtlasPlayer>
[MutationTypes.SYNC_PLAYERS](state: S, keep: Set<string>): void
[MutationTypes.CLEAR_PLAYERS](state: S): void
[MutationTypes.SET_CURRENT_SERVER](state: S, server: string): void
@ -80,8 +79,8 @@ export type Mutations<S = State> = {
[MutationTypes.SET_PARSED_URL](state: S, payload: LiveAtlasParsedUrl): void
[MutationTypes.CLEAR_PARSED_URL](state: S): void
[MutationTypes.CLEAR_CURRENT_MAP](state: S): void
[MutationTypes.SET_FOLLOW_TARGET](state: S, payload: DynmapPlayer): void
[MutationTypes.SET_PAN_TARGET](state: S, payload: DynmapPlayer): void
[MutationTypes.SET_FOLLOW_TARGET](state: S, payload: LiveAtlasPlayer): void
[MutationTypes.SET_PAN_TARGET](state: S, payload: LiveAtlasPlayer): void
[MutationTypes.CLEAR_FOLLOW_TARGET](state: S, a?: void): void
[MutationTypes.CLEAR_PAN_TARGET](state: S, a?: void): void
@ -406,31 +405,31 @@ export const mutations: MutationTree<State> & Mutations = {
},
// Set up to 10 players at once
[MutationTypes.SET_PLAYERS_ASYNC](state: State, players: Set<DynmapPlayer>): Set<DynmapPlayer> {
[MutationTypes.SET_PLAYERS_ASYNC](state: State, players: Set<LiveAtlasPlayer>): Set<LiveAtlasPlayer> {
let count = 0;
for(const player of players) {
if(state.players.has(player.account)) {
const existing = state.players.get(player.account);
if(state.players.has(player.name)) {
const existing = state.players.get(player.name);
existing!.health = player.health;
existing!.armor = player.armor;
existing!.location = Object.assign(existing!.location, player.location);
existing!.hidden = player.hidden;
existing!.name = player.name;
existing!.displayName = player.displayName;
existing!.sort = player.sort;
if(existing!.name !== player.name || existing!.sort !== player.sort) {
if(existing!.displayName !== player.displayName || existing!.sort !== player.sort) {
state.sortedPlayers.dirty = true;
}
} else {
state.sortedPlayers.dirty = true;
state.players.set(player.account, {
account: player.account,
state.players.set(player.name, {
name: player.name,
health: player.health,
armor: player.armor,
location: player.location,
name: player.name,
displayName: player.displayName,
sort: player.sort,
hidden: player.hidden,
});
@ -450,7 +449,7 @@ export const mutations: MutationTree<State> & Mutations = {
return a.sort - b.sort;
}
return a.account.toLowerCase().localeCompare(b.account.toLowerCase());
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
}) as LiveAtlasSortedPlayers;
}
@ -460,7 +459,7 @@ export const mutations: MutationTree<State> & Mutations = {
//Removes all players not found in the provided keep set
[MutationTypes.SYNC_PLAYERS](state: State, keep: Set<string>) {
for(const [key, player] of state.players) {
if(!keep.has(player.account)) {
if(!keep.has(player.name)) {
state.sortedPlayers.splice(state.sortedPlayers.indexOf(player), 1);
state.players.delete(key);
}
@ -547,12 +546,12 @@ export const mutations: MutationTree<State> & Mutations = {
},
//Set the follow target, which the map will automatically pan to keep in view
[MutationTypes.SET_FOLLOW_TARGET](state: State, player: DynmapPlayer) {
[MutationTypes.SET_FOLLOW_TARGET](state: State, player: LiveAtlasPlayer) {
state.followTarget = player;
},
//Set the pan target, which the map will immediately pan to once
[MutationTypes.SET_PAN_TARGET](state: State, player: DynmapPlayer) {
[MutationTypes.SET_PAN_TARGET](state: State, player: LiveAtlasPlayer) {
state.panTarget = player;
},

View File

@ -16,7 +16,6 @@
import {
DynmapComponentConfig, DynmapMarkerSet, DynmapMarkerSetUpdates,
DynmapPlayer,
DynmapServerConfig, DynmapTileUpdate,
DynmapChat
} from "@/dynmap";
@ -29,7 +28,7 @@ import {
LiveAtlasUIElement,
LiveAtlasWorldDefinition,
LiveAtlasParsedUrl,
LiveAtlasMessageConfig, LiveAtlasMapProvider
LiveAtlasMessageConfig, LiveAtlasMapProvider, LiveAtlasPlayer
} from "@/index";
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
@ -45,7 +44,7 @@ export type State = {
worlds: Map<string, LiveAtlasWorldDefinition>;
maps: Map<string, LiveAtlasMapDefinition>;
players: Map<string, DynmapPlayer>;
players: Map<string, LiveAtlasPlayer>;
sortedPlayers: LiveAtlasSortedPlayers;
markerSets: Map<string, DynmapMarkerSet>;
@ -57,8 +56,8 @@ export type State = {
pendingSetUpdates: Map<string, DynmapMarkerSetUpdates>;
pendingTileUpdates: Array<DynmapTileUpdate>;
followTarget?: DynmapPlayer;
panTarget?: DynmapPlayer;
followTarget?: LiveAtlasPlayer;
panTarget?: LiveAtlasPlayer;
currentMapProvider?: Readonly<LiveAtlasMapProvider>;
currentServer?: LiveAtlasServerDefinition;

View File

@ -14,9 +14,9 @@
* limitations under the License.
*/
import {DynmapPlayer} from "@/dynmap";
import {useStore} from "@/store";
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
import {LiveAtlasPlayer} from "@/index";
interface HeadQueueEntry {
cacheKey: string;
@ -52,8 +52,8 @@ export const getMinecraftTime = (serverTime: number) => {
};
}
export const getMinecraftHead = (player: DynmapPlayer | string, size: string): Promise<HTMLImageElement> => {
const account = typeof player === 'string' ? player : player.account,
export const getMinecraftHead = (player: LiveAtlasPlayer | string, size: string): Promise<HTMLImageElement> => {
const account = typeof player === 'string' ? player : player.name,
cacheKey = `${account}-${size}`;
if(headCache.has(cacheKey)) {