Fix #2088
Add an autocomplete with known server names to the connect dialog; Added support for server messages (identification, shutdown, user warning and promotion) Connection dialog’s inputs are now wider Only declare implemented client features Added check for protocol version on connect before login Avoid listbox being rendered as dropdown on mobiles
This commit is contained in:
parent
8644016d3c
commit
a68df3611b
3 changed files with 151 additions and 17 deletions
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue