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> <html>
<head> <head>
<title>Cockatrice web client</title> <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="js/jquery-ui-1.11.4.css">
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
</head> </head>
@ -15,6 +16,7 @@ Loading cockatrice web client...
</div> </div>
<div id="error-dialog" title="Error" style="display:none"></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"> <div id="tabs" style="display:none">
<ul> <ul>
@ -26,7 +28,7 @@ Loading cockatrice web client...
<div id="tab-login"> <div id="tab-login">
<h3>Login to server</h3> <h3>Login to server</h3>
<label for="host">Host</label> <label for="host">Host</label>
<input type="text" id="host" value="127.0.0.1" /> <input type="text" id="host" value="" />
<br/> <br/>
<label for="port">Port</label> <label for="port">Port</label>
<input type="text" id="port" value ="4748" /> <input type="text" id="port" value ="4748" />
@ -54,11 +56,11 @@ Loading cockatrice web client...
<div id="tab-account"> <div id="tab-account">
<div class="buddies-container"> <div class="buddies-container">
<h3>Buddies</h3> <h3>Buddies</h3>
<select id="buddies" size="10"></select> <ul id="buddies" size="10"></ul>
</div> </div>
<div class="ignores-container"> <div class="ignores-container">
<h3>Ignores</h3> <h3>Ignores</h3>
<select id="ignores" size="10"></select> <ul id="ignores" size="10"></ul>
</div> </div>
<div class="userinfo-container"> <div class="userinfo-container">
<h3>User info</h3> <h3>User info</h3>
@ -86,6 +88,16 @@ Loading cockatrice web client...
$("#loading").hide(); $("#loading").hide();
$("#tabs").show(); $("#tabs").show();
$( "#host" ).autocomplete({
source: [
// add custom servers here
"cockatrice.woogerworks.com",
"vps.poixen.com",
"chickatrice.net",
"127.0.0.1"
]
});
$( document ).ready(function() { $( document ).ready(function() {
function ts2time(ts) { function ts2time(ts) {
@ -102,6 +114,43 @@ Loading cockatrice web client...
return $("<div>").text(msg).html(); 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) function timeAgoToInterval(secs)
{ {
var days = Math.floor(secs / 86400); var days = Math.floor(secs / 86400);
@ -205,8 +254,29 @@ Loading cockatrice web client...
$(".room-header, .room-container").remove(); $(".room-header, .room-container").remove();
}, },
"serverMessageCallback" : function(message) { "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) { "userInfoCallback" : function(data) {
$("#userinfo").empty(); $("#userinfo").empty();
$.each(data.userInfo, function(key, value) { $.each(data.userInfo, function(key, value) {
@ -240,13 +310,16 @@ Loading cockatrice web client...
$('#buddies').empty(); $('#buddies').empty();
$.each(data.buddyList, function(key, value) { $.each(data.buddyList, function(key, value) {
$('#buddies').append('<option>' + value.name + '</option>'); debugger;
$('#buddies').append('<li>' + value.name + '</li>');
}); });
$("#buddies").selectable();
$('#ignores').empty(); $('#ignores').empty();
$.each(data.ignoreList, function(key, value) { $.each(data.ignoreList, function(key, value) {
$('#ignores').append('<option>' + value.name + '</option>'); $('#ignores').append('<li>' + value.name + '</li>');
}); });
$("#ignores").selectable();
$("#features").empty(); $("#features").empty();
$.each(data.missingFeatures, function(key, value) { $.each(data.missingFeatures, function(key, value) {
@ -262,14 +335,14 @@ Loading cockatrice web client...
$("#error-dialog").dialog(); $("#error-dialog").dialog();
}, },
"joinRoomCallback" : function(room) { "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>" "<li class='room-header'><a href='#tab-room-" + room["roomId"] + "'>" + room["name"] + "</a></li>"
); );
$("div#tabs").append( $("div#tabs").append(
"<div class='room-container' id='tab-room-" + room["roomId"] + "'>" + "<div class='room-container' id='tab-room-" + room["roomId"] + "'>" +
"<div class='userlist-container'>" + "<div class='userlist-container'>" +
"<h3>Userlist</h3>" + "<h3>Userlist</h3>" +
"<select class=\"userlist\" size=\"10\"></select>" + "<ul class=\"userlist\" size=\"10\"></ul>" +
"</div><div class='chat-container'>" + "</div><div class='chat-container'>" +
"<h3>Chat</h3>" + "<h3>Chat</h3>" +
"<div class=\"output\"></div>" + "<div class=\"output\"></div>" +
@ -281,8 +354,9 @@ Loading cockatrice web client...
$("#tab-room-" + room["roomId"] + " .userlist").empty(); $("#tab-room-" + room["roomId"] + " .userlist").empty();
$.each(room["userList"], function(key, value) { $.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() { $("#tab-room-" + room["roomId"] + " .say").click(function() {
var msg = $("#tab-room-" + room["roomId"] + " .input").val(); var msg = $("#tab-room-" + room["roomId"] + " .input").val();

View file

@ -24,6 +24,7 @@ h3 {
#tab-login input { #tab-login input {
margin-bottom: 10px; margin-bottom: 10px;
width: 20em;
} }
#loading { #loading {
@ -33,7 +34,7 @@ h3 {
} }
.output, #servermessages { .output, #servermessages {
min-height: 400px; height: 400px;
overflow-x: hidden; overflow-x: hidden;
overflow-y: scroll; overflow-y: scroll;
word-wrap: break-word; word-wrap: break-word;
@ -44,7 +45,7 @@ h3 {
} }
.input { .input {
width:93%; width:92%;
} }
.say { .say {
@ -75,7 +76,27 @@ h3 {
#buddies, #ignores, .userlist { #buddies, #ignores, .userlist {
width: 100%; 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 { .buddies-container, .ignores-container, .userinfo-container, .missingfeatures-container {

View file

@ -9,6 +9,7 @@ var StatusEnum = {
var WebClient = { var WebClient = {
status : StatusEnum.DISCONNECTED, status : StatusEnum.DISCONNECTED,
protocolVersion : 14,
socket : 0, socket : 0,
keepalivecb: null, keepalivecb: null,
lastPingPending: false, lastPingPending: false,
@ -39,6 +40,9 @@ var WebClient = {
"pb/response_login.proto", "pb/response_login.proto",
"pb/session_event.proto", "pb/session_event.proto",
"pb/event_server_message.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_connection_closed.proto",
"pb/event_list_rooms.proto", "pb/event_list_rooms.proto",
"pb/response_join_room.proto", "pb/response_join_room.proto",
@ -157,8 +161,14 @@ var WebClient = {
"userName" : this.options.user, "userName" : this.options.user,
"password" : this.options.pass, "password" : this.options.pass,
"clientid" : this.guid(), "clientid" : this.guid(),
"clientver" : "webclient-0.1 (2015-12-23)", "clientver" : "webclient-0.2 (2016-08-03)",
"clientfeatures" : [ "client_id", "client_ver"], "clientfeatures" : [
"client_id",
"client_ver",
"feature_set",
"room_chat_history",
"client_warnings"
]
}); });
var sc = new WebClient.pb.SessionCommand({ var sc = new WebClient.pb.SessionCommand({
@ -293,6 +303,37 @@ var WebClient = {
} }
return; 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) processRoomEvent : function (raw)
@ -348,9 +389,7 @@ var WebClient = {
} }
this.socket.onopen = function(){ this.socket.onopen = function(){
WebClient.setStatus(StatusEnum.CONNECTED, 'Connected, logging in...'); WebClient.setStatus(StatusEnum.CONNECTED, 'Connected');
WebClient.resetConnectionvars();
WebClient.doLogin();
} }
this.socket.onmessage = function(event) { this.socket.onmessage = function(event) {