Files
erqiwang_youle/server/YouLeGamesServer.html

550 lines
14 KiB
HTML

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1 user-scalable=0"/>
<title>友乐游戏平台服务器</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
background: #f0f2f5;
color: #1f2328;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 13px;
height: 100vh;
display: flex;
flex-direction: column;
}
#app {
display: flex;
flex-direction: column;
height: 100vh;
padding: 8px;
gap: 6px;
}
/* ---- 顶部标题栏 ---- */
#header {
display: flex;
align-items: center;
justify-content: space-between;
background: #ffffff;
border: 1px solid #d0d7de;
border-radius: 6px;
padding: 8px 14px;
flex-shrink: 0;
box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}
#title {
font-size: 15px;
font-weight: bold;
color: #0969da;
letter-spacing: 1px;
}
#srv-status { font-size: 13px; }
.status-connected { color: #1a7f37; }
.status-disconnected { color: #cf222e; }
.status-connecting { color: #9a6700; }
/* ---- 工具栏 ---- */
#toolbar {
display: flex;
align-items: center;
gap: 8px;
background: #ffffff;
border: 1px solid #d0d7de;
border-radius: 6px;
padding: 5px 10px;
flex-shrink: 0;
box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}
#toolbar button {
background: #f6f8fa;
color: #57606a;
border: 1px solid #d0d7de;
border-radius: 4px;
padding: 3px 10px;
cursor: pointer;
font-size: 12px;
font-family: inherit;
transition: background 0.15s, color 0.15s;
}
#toolbar button:hover { background: #e8eef4; color: #1f2328; }
#toolbar button.active { color: #1a7f37; border-color: #1a7f37; background: #dafbe1; }
#log-count {
margin-left: auto;
color: #8c959f;
font-size: 12px;
white-space: nowrap;
}
/* ---- 日志区域 ---- */
#log-container {
flex: 1;
overflow-y: auto;
background: #ffffff;
border: 1px solid #d0d7de;
border-radius: 6px;
padding: 6px 8px;
line-height: 1.65;
min-height: 0;
box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}
#log-container::-webkit-scrollbar { width: 6px; }
#log-container::-webkit-scrollbar-track { background: #f6f8fa; }
#log-container::-webkit-scrollbar-thumb { background: #d0d7de; border-radius: 3px; }
.log-line {
padding: 1px 4px;
border-radius: 2px;
word-break: break-all;
white-space: pre-wrap;
}
.log-line:hover { background: rgba(0,0,0,0.04); }
/* 日志类型颜色 */
.log-info { color: #57606a; }
.log-system { color: #0969da; }
.log-success { color: #1a7f37; }
.log-warning { color: #9a6700; }
.log-error { color: #cf222e; }
.log-data { color: #8250df; }
</style>
</head>
<body>
<div id="app">
<div id="header">
<span id="title">&#9679; 友乐游戏平台服务器</span>
<span id="srv-status" class="status-disconnected">● 未连接</span>
</div>
<div id="toolbar">
<button onclick="clearLog()">清空日志</button>
<button id="btn-autoscroll" class="active" onclick="toggleAutoScroll()">自动滚动 ✓</button>
<span id="log-count">共 0 条</span>
</div>
<div id="log-container"></div>
</div>
<script type="text/javascript" src="md5.js"></script>
<script type="text/javascript" src="indexDb.js"></script>
<script type="text/javascript" src="lz-string.js"></script>
<script type="text/javascript" src="minhttp.js"></script>
<script type="text/javascript" src="packet.js"></script>
<script type="text/javascript">
// Websocket object
var ws = null;
// Websocket 连接地址
var ws_url = "ws://127.0.0.1:3088";
//临时屏蔽某个游戏的数据包
var blacknamelist_game = [];
// 日志控制
var _autoScroll = true;
var _logCount = 0;
var MAX_LOG_LINES = 500;
// Helper functions
function $() {
return document.getElementById(arguments[0]);
}
function _getLogClass(msg) {
var m = (msg || '').toLowerCase();
if (m.indexOf('error') > -1 || m.indexOf('报错') > -1 || m.indexOf('非法') > -1 || m.indexOf('出错') > -1) return 'log-error';
if (m.indexOf('close') > -1 || m.indexOf('断开') > -1 || m.indexOf('disconn') > -1) return 'log-warning';
if (m.indexOf('connected') > -1 || m.indexOf('连接') > -1 || m.indexOf('login') > -1) return 'log-success';
if (m.indexOf('tcp') > -1 || m.indexOf('http') > -1 || m.indexOf('ws:') > -1) return 'log-system';
return 'log-info';
}
function logMsg(msg) {
var container = $('log-container');
if (!container) return;
_logCount++;
// 超出上限时移除最早的一行
if (container.children.length >= MAX_LOG_LINES) {
container.removeChild(container.firstChild);
}
var line = document.createElement('div');
line.className = 'log-line ' + _getLogClass(msg);
line.textContent = msg;
container.appendChild(line);
$('log-count').textContent = '共 ' + _logCount + ' 条';
if (_autoScroll) {
container.scrollTop = container.scrollHeight;
}
}
function logmsg(msg) {
logMsg(msg);
}
function clearLog() {
var container = $('log-container');
container.innerHTML = '';
_logCount = 0;
$('log-count').textContent = '共 0 条';
}
function toggleAutoScroll() {
_autoScroll = !_autoScroll;
var btn = $('btn-autoscroll');
btn.textContent = _autoScroll ? '自动滚动 ✓' : '自动滚动 ✗';
btn.className = _autoScroll ? 'active' : '';
}
function setStatus(state) {
var el = $('srv-status');
if (state === 'connected') {
el.className = 'status-connected';
el.textContent = '● 已连接';
} else if (state === 'connecting') {
el.className = 'status-connecting';
el.textContent = '● 连接中…';
} else {
el.className = 'status-disconnected';
el.textContent = '● 未连接';
}
}
function sendMsg(msg) {
try{
ws.send(msg);
}catch(e){
console.log(min_now() + "发包报错。");
console.log(msg);
console.log(e);
}
}
function sendmsg(msg) {
try{
ws.send(msg);
}catch(e){
console.log(min_now() + "发包报错。");
console.log(msg);
console.log(e);
}
}
//重新连接
function reconnect(){
ws = null;
connectWebSocket();
}
// Websocket functions
function connectWebSocket() {
OnBeginConnectedServerChat();
if ("WebSocket" in window) {
// Create new websocket connection
setStatus('connecting');
ws = new WebSocket(ws_url);
// Called after connection is established
ws.onopen = function() {
setStatus('connected');
logMsg(min_now() + ' tcp connected to: ' + ws.url);
sendMsg('dfw19770109'); //告诉ServerChat.exe我是逻辑服务器
ws.wsisclose = false;
};
// Called when connection is closed
ws.onclose = function() {
ws.wsisclose = true;
setStatus('disconnected');
logMsg(min_now() + " Connection closed!");
ws.reconnecttimer = min_ontimeout(reconnect, 5000);
};
// Called when a new message is received
ws.sendall = function (msg) {
if (ws.wsisclose){
return;
}
if (typeof(msg) == 'string') {
sendMsg('@toallall:' + msg);
}
else
{
var s = JSON.stringify(msg);
sendMsg('@toallall:' + s);
}
}
//Send message to HTTP client
ws.sendtou = function (head, msg) {
if (ws.wsisclose){
return;
}
sendMsg(head + msg);
}
//Send message to TCP client
ws.sendbyids = function(ids, msg) {
if (ws.wsisclose){
return;
}
var s = '@tooneone:';
var str_ids;
if (typeof(msg) == 'string')
{}
else
{
msg = JSON.stringify(msg);
}
if (typeof(ids) == 'string')
{
str_ids = ids;
}
else
{
//ids:[1,5,8] 要转成字符串 1,5,8
str_ids = ids[0];
for (var i=1; i<ids.length; i++)
{
str_ids = str_ids + ',' + ids[i];
}
}
s = s + str_ids + ':' + msg;
sendMsg(s);
}
ws.sendclosetcp = function(ids) {
if (ws.wsisclose){
return;
}
var s = '@toclosed:';
var str_ids;
if (typeof(ids) == 'string') {
str_ids = ids;
}else{
//ids:[1,5,8] 要转成字符串 1,5,8
str_ids = ids[0];
for (var i=1; i<ids.length; i++)
{
str_ids = str_ids + ',' + ids[i];
}
}
s = s + str_ids+ ':a';
sendMsg(s);
}
ws.onmessage = function (msg) {
if (msg.data)
{
// logMsg(msg.data);
var arr = msg.data;
var tou = arr.substr(10, 5);
// var arrs = arr.split(":");
//取前面50个字符,以免全字符split,提高效率
var arr50 = arr.substr(0, 50);
var arrs = arr50.split(":");
if (tou == 'http_')
{//http
var s1 = '@tooneone' + ':' + arrs[1] + ':';
var s2 = "";
if (arrs.length > 2)
{//是数据,否则是命令
s2 = msg.data.substr(s1.length, msg.data.length-s1.length);
}
OnHttpMessage(s1, s2);
}
else
{//tcp
var ss0 = arrs[0];
var ss1 = arrs[1];
var sip = arrs[2];
var s01 = ss0 + ':' + ss1 + ':' + sip + ':';
var ss2 = "";
if (arrs.length > 3)
{//是数据,否则是命令
ss2 = msg.data.substr(s01.length, msg.data.length - s01.length);
}
OnTcpMessage(ss0, ss1, sip, ss2);
// var ss0 = arrs[0];
// var ss1 = arrs[1];
// var s01 = ss0 + ':' + ss1 + ':';
// var ss2 = "";
// if (arrs.length > 2)
// {//是数据,否则是命令
// ss2 = msg.data.substr(s01.length, msg.data.length - s01.length);
// }
// OnTcpMessage(ss0, ss1, "", ss2);
}
};
return;
};
}
else
{
logMsg('Browser doesn\'t support websockets!');
}
OnAfterConnectedServerChat();
}
//server.html连接ServerChat.exe前的事件
function OnBeginConnectedServerChat()
{
}
//server.html连接ServerChat.exe后的事件
function OnAfterConnectedServerChat()
{
//给packet_face传递发包函数
if (typeof(packet_face) != "undefined")
{
global.packet_face.SendPack_Tcp = ws.sendbyids;
global.packet_face.SendPack_Http = ws.sendtou;
}
}
//收到客户端http发包触发的事件
function OnHttpMessage(str_httpid, str_data)
{
try
{
str_data = min_replaceAll(str_data, "%", "");
str_data = decodeURIComponent(str_data); //解码
}
catch(e)
{
console.log("OnHttpMessage_decodeURIComponent:" + str_data);
return;
}
var s = "";
s = str_data.substr(0, 6);
if (s == "&data=") {
str_data = str_data.replace("&data=", "");
}
s = str_data.substr(0, 5);
if (s == "data=") {
str_data = str_data.replace("data=", "");
}
s = str_data.substr(0, 2);
if (s == "&=") {
str_data = str_data.replace("&=", "");
}
s = str_data.substr(0, 1);
if (s == "&") {
str_data = str_data.replace("&", "");
}
if (typeof(packet_face) != "undefined") {
if (str_data) {
try
{
var json_data = JSON.parse(str_data);
if (json_data){
json_data.conmode = "http";
json_data.fromid = str_httpid;
packet_face.ReceivePack(json_data);
}
}
catch(e)
{
console.log(min_now() + " str_data:" + str_data);
console.log(e);
}
}
}
}
//收到客户端tcp发包触发的事件
function OnTcpMessage(str_com, str_tcpid, str_ip, str_data)
{
switch (str_com)
{
case "@toconcon": //连上ServerChat.exe
break;
case "@tologin1": //客户端连接上
if (typeof(packet_face) != "undefined")
{
packet_face.OnTcpConnected(str_tcpid);
}
break;
case "@toleave1": //客户端断开
if (typeof(packet_face) != "undefined")
{
packet_face.OnTcpDisConnected(str_tcpid);
}
break;
case "@toserver": //客户端发包
if (typeof(packet_face) != "undefined")
{
try
{
//去除%,否则decodeURIComponent(str_data)会报错
str_data = min_replaceAll(str_data, "%", "");
//解码
str_data = decodeURIComponent(str_data);
var json_data = JSON.parse(str_data);
}
catch(e)
{
console.log(min_now() + "非法的TCP连接");
var errlog = {};
errlog.com = str_com;
errlog.tcpid = str_tcpid;
errlog.ip = str_ip;
errlog.data = str_data;
console.log(errlog);
//断开tcp连接
ws.sendclosetcp(str_tcpid);
return;
}
if (json_data){
try
{
//屏蔽某个有错的route
if (json_data.route){
if (min_ary_indexof(blacknamelist_game, json_data.route) > -1){
return;
}
}
}
catch(e)
{}
json_data.conmode = "tcp";
json_data.fromid = str_tcpid;
json_data.ip = str_ip;
try
{
packet_face.ReceivePack(json_data);
}
catch(e)
{
console.log(min_now() + "执行rpc出错");
console.log(json_data);
console.log(e);
}
}
}
break;
default:
console.log(min_now() + "非法的TCP连接");
var errlog = {};
errlog.com = str_com;
errlog.tcpid = str_tcpid;
errlog.ip = str_ip;
errlog.data = str_data;
console.log(errlog);
//断开tcp连接
ws.sendclosetcp(str_tcpid);
break;
}
}
window.onload = connectWebSocket();
</script>
</body>
</html>