Merge pull request #2117 from ctrlaltca/fix_2088

Webclient: misc improvements (was: parse html in server message)
This commit is contained in:
ctrlaltca 2016-08-09 11:14:01 +02:00 committed by GitHub
commit ac841ee2c6
3 changed files with 151 additions and 17 deletions

View file

@ -2,6 +2,7 @@
<html>
<head>
<title>Cockatrice web client</title>
<link rel="shortcut icon" href="imgs/cockatrice.png" />
<link rel="stylesheet" href="js/jquery-ui-1.11.4.css">
<link rel="stylesheet" href="style.css">
</head>
@ -15,6 +16,7 @@ Loading cockatrice web client...
</div>
<div id="error-dialog" title="Error" style="display:none"></div>
<div id="info-dialog" title="Information" style="display:none"></div>
<div id="tabs" style="display:none">
<ul>
@ -26,7 +28,7 @@ Loading cockatrice web client...
<div id="tab-login">
<h3>Login to server</h3>
<label for="host">Host</label>
<input type="text" id="host" value="127.0.0.1" />
<input type="text" id="host" value="" />
<br/>
<label for="port">Port</label>
<input type="text" id="port" value ="4748" />
@ -54,11 +56,11 @@ Loading cockatrice web client...
<div id="tab-account">
<div class="buddies-container">
<h3>Buddies</h3>
<select id="buddies" size="10"></select>
<ul id="buddies" size="10"></ul>
</div>
<div class="ignores-container">
<h3>Ignores</h3>
<select id="ignores" size="10"></select>
<ul id="ignores" size="10"></ul>
</div>
<div class="userinfo-container">
<h3>User info</h3>
@ -86,6 +88,16 @@ Loading cockatrice web client...
$("#loading").hide();
$("#tabs").show();
$( "#host" ).autocomplete({
source: [
// add custom servers here
"cockatrice.woogerworks.com",
"vps.poixen.com",
"chickatrice.net",
"127.0.0.1"
]
});
$( document ).ready(function() {
function ts2time(ts) {
@ -102,6 +114,43 @@ Loading cockatrice web client...
return $("<div>").text(msg).html();
}
function htmlSanitize(msg) {
var div = $("<div>").html(msg);
// remove all tags except some
var tagsWhitelist = "br,a,img,center,b,font";
$(div).find("*").not(tagsWhitelist).each(function() {
$(this).replaceWith(this.innerHTML);
});
// remove all attributes except some
var attributesWhitelist = ["href","color"];
$(div).find("*").each(function() {
var attributes = this.attributes;
var i = attributes.length;
while( i-- ) {
var attr = attributes[i];
if( $.inArray(attr.name,attributesWhitelist) == -1 )
this.removeAttributeNode(attr);
}
});
// permit only some protocols in href
var hrefWhitelist = ["http://","https://","ftp://","//"];
$(div).find("[href]").each(function() {
var attributeValue = $(this).attr('href');
for(var protocol in hrefWhitelist)
if(attributeValue.indexOf(hrefWhitelist[protocol]) == 0)
return;
$(this).removeAttr('href');
});
return $(div).html();
}
function timeAgoToInterval(secs)
{
var days = Math.floor(secs / 86400);
@ -205,8 +254,29 @@ Loading cockatrice web client...
$(".room-header, .room-container").remove();
},
"serverMessageCallback" : function(message) {
$("#servermessages").append(htmlEscape(message) + '<br/>');
$("#servermessages").append(htmlSanitize(message) + '<br/>');
},
"serverIdentificationCallback" : function(data) {
console.log('Connected to: ' + data.serverName + ' version ' + data.serverVersion + ' protocol ' + data.protocolVersion);
},
"serverShutdownCallback" : function(data) {
$("#info-dialog").text('The server is going to be restarted in ' + data.minutes + ' minute(s).\nAll running games will be lost.\nReason for shutdown: ' + data.reason);
$("#info-dialog").dialog();
},
"notifyUserCallback" : function(data) {
switch(data.type)
{
case WebClient.pb.Event_NotifyUser.NotificationType.PROMOTED:
$("#info-dialog").text('You have been promoted to moderator. Please log out and back in for changes to take effect.');
$("#info-dialog").dialog();
break;
case WebClient.pb.Event_NotifyUser.NotificationType.WARNING:
$("#info-dialog").text('You have received a warning due to ' + data.warningReason + '.\nPlease refrain from engaging in this activity or further actions may be taken against you. If you have any questions, please private message a moderator.');
$("#info-dialog").dialog();
break;
}
},
"userInfoCallback" : function(data) {
$("#userinfo").empty();
$.each(data.userInfo, function(key, value) {
@ -240,13 +310,16 @@ Loading cockatrice web client...
$('#buddies').empty();
$.each(data.buddyList, function(key, value) {
$('#buddies').append('<option>' + value.name + '</option>');
debugger;
$('#buddies').append('<li>' + value.name + '</li>');
});
$("#buddies").selectable();
$('#ignores').empty();
$.each(data.ignoreList, function(key, value) {
$('#ignores').append('<option>' + value.name + '</option>');
$('#ignores').append('<li>' + value.name + '</li>');
});
$("#ignores").selectable();
$("#features").empty();
$.each(data.missingFeatures, function(key, value) {
@ -262,14 +335,14 @@ Loading cockatrice web client...
$("#error-dialog").dialog();
},
"joinRoomCallback" : function(room) {
$("div#tabs ul").append(
$("div#tabs > ul").append(
"<li class='room-header'><a href='#tab-room-" + room["roomId"] + "'>" + room["name"] + "</a></li>"
);
$("div#tabs").append(
"<div class='room-container' id='tab-room-" + room["roomId"] + "'>" +
"<div class='userlist-container'>" +
"<h3>Userlist</h3>" +
"<select class=\"userlist\" size=\"10\"></select>" +
"<ul class=\"userlist\" size=\"10\"></ul>" +
"</div><div class='chat-container'>" +
"<h3>Chat</h3>" +
"<div class=\"output\"></div>" +
@ -281,8 +354,9 @@ Loading cockatrice web client...
$("#tab-room-" + room["roomId"] + " .userlist").empty();
$.each(room["userList"], function(key, value) {
$("#tab-room-" + room["roomId"] + " .userlist").append('<option>' + value.name + '</option>');
$("#tab-room-" + room["roomId"] + " .userlist").append('<li>' + value.name + '</li>');
});
$("#tab-room-" + room["roomId"] + " .userlist").selectable();
$("#tab-room-" + room["roomId"] + " .say").click(function() {
var msg = $("#tab-room-" + room["roomId"] + " .input").val();

View file

@ -24,6 +24,7 @@ h3 {
#tab-login input {
margin-bottom: 10px;
width: 20em;
}
#loading {
@ -33,7 +34,7 @@ h3 {
}
.output, #servermessages {
min-height: 400px;
height: 400px;
overflow-x: hidden;
overflow-y: scroll;
word-wrap: break-word;
@ -44,7 +45,7 @@ h3 {
}
.input {
width:93%;
width:92%;
}
.say {
@ -75,7 +76,27 @@ h3 {
#buddies, #ignores, .userlist {
width: 100%;
min-height: 470px;
height: 500px;
list-style-type: none;
overflow-x: hidden;
overflow-y: scroll;
background: #fff;
padding: 0;
margin: 0;
cursor: pointer;
border: 1px solid #999;
}
#buddies li, #ignores li, .userlist li {
padding: 0 3px;
}
#buddies .ui-selecting, #ignores .ui-selecting, .userlist .ui-selecting {
background: #FECA40;
}
#buddies .ui-selected, #ignores .ui-selected, .userlist .ui-selected {
background: #F39814; color: white;
}
.buddies-container, .ignores-container, .userinfo-container, .missingfeatures-container {

View file

@ -9,6 +9,7 @@ var StatusEnum = {
var WebClient = {
status : StatusEnum.DISCONNECTED,
protocolVersion : 14,
socket : 0,
keepalivecb: null,
lastPingPending: false,
@ -39,6 +40,9 @@ var WebClient = {
"pb/response_login.proto",
"pb/session_event.proto",
"pb/event_server_message.proto",
"pb/event_server_identification.proto",
"pb/event_server_shutdown.proto",
"pb/event_notify_user.proto",
"pb/event_connection_closed.proto",
"pb/event_list_rooms.proto",
"pb/response_join_room.proto",
@ -157,8 +161,14 @@ var WebClient = {
"userName" : this.options.user,
"password" : this.options.pass,
"clientid" : this.guid(),
"clientver" : "webclient-0.1 (2015-12-23)",
"clientfeatures" : [ "client_id", "client_ver"],
"clientver" : "webclient-0.2 (2016-08-03)",
"clientfeatures" : [
"client_id",
"client_ver",
"feature_set",
"room_chat_history",
"client_warnings"
]
});
var sc = new WebClient.pb.SessionCommand({
@ -293,6 +303,37 @@ var WebClient = {
}
return;
}
if(raw[".Event_ServerIdentification.ext"]) {
if(this.options.serverIdentificationCallback)
this.options.serverIdentificationCallback(
raw[".Event_ServerIdentification.ext"]
);
if(raw[".Event_ServerIdentification.ext"].protocolVersion != WebClient.protocolVersion)
{
WebClient.socket.close();
WebClient.setStatus(StatusEnum.DISCONNECTED, 'Protocol version mismatch: ' + raw[".Event_ServerIdentification.ext"].protocolVersion);
return;
}
WebClient.setStatus(StatusEnum.CONNECTED, 'Logging in...');
WebClient.resetConnectionvars();
WebClient.doLogin();
return;
}
if(raw[".Event_ServerShutdown.ext"]) {
if(this.options.serverShutdownCallback)
this.options.serverShutdownCallback(raw[".Event_ServerShutdown.ext"]);
return;
}
if(raw[".Event_NotifyUser.ext"]) {
if(this.options.notifyUserCallback)
this.options.notifyUserCallback(raw[".Event_NotifyUser.ext"]);
return;
}
},
processRoomEvent : function (raw)
@ -348,9 +389,7 @@ var WebClient = {
}
this.socket.onopen = function(){
WebClient.setStatus(StatusEnum.CONNECTED, 'Connected, logging in...');
WebClient.resetConnectionvars();
WebClient.doLogin();
WebClient.setStatus(StatusEnum.CONNECTED, 'Connected');
}
this.socket.onmessage = function(event) {