Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions PapyrusCs/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ public class Options
[Option("use_leaflet_legacy", Required = false, Default = false, HelpText = "Use the legacy leaflet.js map renderer instead of the new OpenLayers version")]
public bool UseLeafletLegacy { get; set; }

[Option("bot_websocket_url", Required = false, Default = "", HelpText = "If you're using Papyrus Bot to monitor chat and player position, provide it's WebSocket URL here")]
public string BotWebsocketUrl { get; set; }


// Derivative options
public bool Loaded { get; set; }
Expand Down
8 changes: 5 additions & 3 deletions PapyrusCs/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ private static int RunMapCommand(Options options)


WriteMapHtml(tileSize, options.OutputPath, options.MapHtml, strat.GetSettings(), strat.IsUpdate,
options.UseLeafletLegacy);
options.UseLeafletLegacy, options.BotWebsocketUrl);

strat.Finish();
Console.WriteLine("Total Time {0}", _time.Elapsed);
Expand Down Expand Up @@ -654,10 +654,11 @@ private class GlobalConfig
public double factor;
public int globalMinZoom;
public int globalMaxZoom;
public string botWebSocketUrl;
}

private static void WriteMapHtml(int tileSize, string outputPath, string mapHtmlFile, Settings[] settings,
bool isUpdate, bool useLegacyLeaflet)
bool isUpdate, bool useLegacyLeaflet, string botWebSocketUrl)
{
try
{
Expand Down Expand Up @@ -695,7 +696,8 @@ private static void WriteMapHtml(int tileSize, string outputPath, string mapHtml
{
factor = (Math.Pow(2, settings.First().MaxZoom - 4)),
globalMaxZoom = settings.First(x => x.Dimension == settings.Min(y => y.Dimension)).MaxZoom,
globalMinZoom = settings.First(x => x.Dimension == settings.Min(y => y.Dimension)).MinZoom
globalMinZoom = settings.First(x => x.Dimension == settings.Min(y => y.Dimension)).MinZoom,
botWebSocketUrl = botWebSocketUrl,
};

mapHtmlContext = mapHtmlContext.Replace(
Expand Down
105 changes: 104 additions & 1 deletion PapyrusCs/map.thtml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@
right: 0.5em;
width: 150px;
}

#chat {
position: absolute;
width: 25vw;
min-width: 300px;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
min-height: 10em;
display: flex;
flex-direction: column-reverse;
padding: 5px;
}

#chat span {
color: white;
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
Expand All @@ -60,6 +76,7 @@
></script>

<div id="map"></div>
<div id="chat" style="display: none;"></div>
<script>
var layers = {
dim0: {
Expand Down Expand Up @@ -159,6 +176,14 @@
let map;
let locationElement;

const vectorSource = new ol.source.Vector({
wrapX: false,
});

const vectorLayer = new ol.layer.Vector({
source: vectorSource,
});

const tileLayers = Object.keys(layers)
.sort()
.map(function(layerKey, idx) {
Expand Down Expand Up @@ -335,7 +360,7 @@

map = new ol.Map({
target: "map",
layers: tileLayers,
layers: [...tileLayers, vectorLayer],
view: view,
controls: [
new ol.control.Zoom(),
Expand All @@ -356,6 +381,84 @@

locationElement.innerText = "X: " + x + " Z: " + z;
});

if (config.botWebSocketUrl.length > 0) {
const chatBox = document.getElementById("chat");
chatBox.style.display = "flex";

const messages = [];
let playerFeatures = {};

const initialMessage = document.createElement("span");
initialMessage.innerText = "Chat messages will appear here.";
initialMessage.style.color = "gray";
initialMessage.style.fontStyle = "italic";
chatBox.appendChild(initialMessage);
messages.push(initialMessage);

function addMessage(m) {
const msgSpan = document.createElement("span");
msgSpan.innerText = m;
chatBox.prepend(msgSpan);
messages.push(msgSpan);

if (messages.length > 10) {
const deleted = messages.splice(0, 1);
for (const del of deleted) {
del.parentElement.removeChild(del);
}
}
}

const webSocket = new WebSocket(config.botWebSocketUrl);
webSocket.addEventListener('open', function(event) {
addMessage('Connected');
});
webSocket.addEventListener('message', function(event) {
const data = JSON.parse(event.data);
switch (data.type) {
case "pos":
const playerName1 = data.playerName;
const x = (data.x / minecraftTilesAtMostZoomedInLevel) * zoomRatioForMaximumZoom;
const z = (data.z / minecraftTilesAtMostZoomedInLevel) * -zoomRatioForMaximumZoom;

if (playerFeatures[playerName1] === undefined) {
playerFeatures[playerName1] = {
pos: [x, z],
feature: null,
}
}

playerFeatures[playerName1].pos = [x, z];

const feature = new ol.Feature({
geometry: new ol.geom.Point(playerFeatures[playerName1].pos),
})

feature.setStyle(new ol.style.Style({
image: new ol.style.Icon(({
color: '#8959A8',
crossOrigin: 'anonymous',
src: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABpUlEQVQ4y7WVPXLbMBBGn+2G6cAOJdypo8qUuEF0A/EGPoKPwMkJPOyois4NWLoUSlXEDbjsoAopBCQaWbSdif3NYIbNvtmfb5c3vC+VHoCkt6ibNyBroALMBdADDthfg18DroEfgAXW6qQTTQQRkQQbgF/pexG4Bh6AjTFGWWupqopzoHOOYRjw3gvwDPy8hJ7DnsqyFGttbJomjuMYLzWOY2yaJlprY1mWAjyl2Fc9ewQma23s+z5O0xSXNE1T7Ps+WmsjMKVYBXCXgN+B2hiz2m63bDabP2VeU1EUaK0JIXA4HIpTWzmkgUHq21TX9dUylzSOY6zrOmf5AHCbUjVKKVVVFcYYPipjTB6ayvbKQKWUerPMRdf/jVMZ+Km6zeuUTPvPgLM4ASQDvYiIcw7v/Ydh3nucc3l7PCDZNt+AlYgYpRSr1YqiKN7NrOs6drsdIvIC7AB/d7b0WkTWx+Ox0FqjtV6EigjDMNC2Lfv9XoAu7XXIwADMgJrn+d57X4QQ0Fq/mrz3nq7raNsW59wcQngG2mzqTz8OX36+vuTA/tcv4DcQ5j3msmvKlAAAAABJRU5ErkJggg=='
}))
}));

if (playerFeatures[playerName1].feature !== null) {
vectorSource.removeFeature(playerFeatures[playerName1].feature);
}

playerFeatures[playerName1].feature = feature;
vectorSource.addFeature(playerFeatures[playerName1].feature);

break;
case "chat":
const playerName2 = data.playerName;
const message = data.message;
addMessage(playerName2 + ": " + message);
break;
}
});
}
</script>
</body>
</html>