chore: remove useless stuff
Stray bits of config, MacOS dashboard widget...
This commit is contained in:
parent
46df0f2d61
commit
3922a78de9
60 changed files with 6 additions and 4929 deletions
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.4 KiB |
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AllowNetworkAccess</key>
|
||||
<true/>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Legacy Worlds</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.widget.legacyworlds</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MainHTML</key>
|
||||
<string>LW.html</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,109 +0,0 @@
|
|||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#mainDiv {
|
||||
position: absolute;
|
||||
top: 35px;
|
||||
left: 7px;
|
||||
width: 307px;
|
||||
height: 290px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#debugLink {
|
||||
position: absolute;
|
||||
top: 326px;
|
||||
left: 30px;
|
||||
width: 271px;
|
||||
height: 14px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#debugDiv {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 35px;
|
||||
left: 7px;
|
||||
width: 307px;
|
||||
height: 290px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
z-index: 1;
|
||||
border: 1px solid #7f7f7f;
|
||||
}
|
||||
|
||||
#debugTable {
|
||||
width: 301px;
|
||||
height: 284px;
|
||||
margin: 3px;
|
||||
padding: 0;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
#debugTable td {
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
tr#dbgHdr {
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
#mainTable {
|
||||
width: 305px;
|
||||
height: 288px;
|
||||
margin: 1px;
|
||||
padding: 0;
|
||||
border: 1px solid #7f7f7f;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
#mtTitle {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
height: 30px;
|
||||
font-size: 18px;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#mtMenu {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
height: 30px;
|
||||
border: 1px solid #7f7f7f;
|
||||
font-size: 12px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#mtContents {
|
||||
color: white;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
a, a:active, a:visited {
|
||||
text-decoration: underline;
|
||||
font-style: italic;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.table {
|
||||
margin: 0% 4%;
|
||||
width: 96%;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.table td {
|
||||
color: white;
|
||||
font-size: 13px;
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@import "LW.css";
|
||||
</style>
|
||||
<!-- DeepClone components library -->
|
||||
<script type='text/javascript' src='lib/Base.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/Base/Util.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/Base/Util/Hashtable.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/Base/Log.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/Base/Comp.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/Base/Comp/Evt.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/Base/Comp/Slot.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/Base/Timer.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/Base/Browser.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/Base/XMLLoader.js' charset='utf-8'></script>
|
||||
<!-- Main widget code -->
|
||||
<script type='text/javascript' src='lib/LWWidget.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Main.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Debug.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/VersionCheck.js' charset='utf-8'></script>
|
||||
<!-- Data management -->
|
||||
<script type='text/javascript' src='lib/LWWidget/Data.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Data/Leaf.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Data/Node.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Data/Loader.js' charset='utf-8'></script>
|
||||
<!-- Menu code -->
|
||||
<script type='text/javascript' src='lib/LWWidget/Menu.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Menu/Mode.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Menu/Item.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Menu/Text.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Menu/Command.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Menu/Entry.js' charset='utf-8'></script>
|
||||
<!-- Top-level pages -->
|
||||
<script type='text/javascript' src='lib/LWWidget/Page.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Login.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/TextPage.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/GameSelector.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/GameDisplay.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/NewVersion.js' charset='utf-8'></script>
|
||||
<!-- Game handling -->
|
||||
<script type='text/javascript' src='lib/LWWidget/Game.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Game/Page.js' charset='utf-8'></script>
|
||||
<!-- Beta 5 -->
|
||||
<script type='text/javascript' src='lib/LWWidget/Beta5.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Beta5/Player.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Beta5/Planets.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Beta5/Fleets.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Beta5/Cash.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Beta5/Techs.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Beta5/Msg.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Beta5/Forums.js' charset='utf-8'></script>
|
||||
<script type='text/javascript' src='lib/LWWidget/Beta5/Ticks.js' charset='utf-8'></script>
|
||||
</head>
|
||||
<body>
|
||||
<img src="Default.png" />
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
|
@ -1,189 +0,0 @@
|
|||
/** This function defines the Base class, from which all other classes are inherited.
|
||||
* The Base class defines a somewhat sound framework for inheritance.
|
||||
*/
|
||||
Base = function () {
|
||||
if (arguments.length) {
|
||||
if (this == window) {
|
||||
Base.prototype.extend.call(arguments[0], arguments.callee.prototype);
|
||||
} else {
|
||||
this.extend(arguments[0]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** This class property lists the functions to be called when the page
|
||||
* containing the code is first loaded.
|
||||
*/
|
||||
Base.initialisers = new Array();
|
||||
|
||||
/** This class property lists the functions to be called when the page
|
||||
* containing the code is unloaded.
|
||||
*/
|
||||
Base.destructors = new Array();
|
||||
|
||||
|
||||
/** This class method adds a function to the list of initialisers.
|
||||
*/
|
||||
Base.registerInitialiser = function (initialiser) {
|
||||
Base.initialisers.push(initialiser);
|
||||
};
|
||||
|
||||
/** This class method adds a function to the list of destructors.
|
||||
*/
|
||||
Base.registerDestructor = function (destructor) {
|
||||
Base.destructors.push(destructor);
|
||||
};
|
||||
|
||||
|
||||
Base.prototype = {
|
||||
/** The extend() method adds a set of methods and properties to an existing object.
|
||||
* @param addition an object containing the methods and properties to add.
|
||||
* @returns the extended object.
|
||||
*/
|
||||
extend: function (addition) {
|
||||
var _o = Base.prototype.overload;
|
||||
|
||||
var _p = { toSource: null };
|
||||
var _l = ['toString', 'valueOf'];
|
||||
if (Base._inherits) {
|
||||
_l.push('constructor');
|
||||
}
|
||||
|
||||
for (var i in _l) {
|
||||
var _n = _l[i];
|
||||
if (addition[_n] != _p[_n]) {
|
||||
_o.call(this, _n, addition[_n]);
|
||||
_p[_n] = addition[_n];
|
||||
}
|
||||
}
|
||||
|
||||
for (var i in addition) {
|
||||
if (_p[i]) {
|
||||
continue;
|
||||
}
|
||||
if (addition[i] instanceof Function) {
|
||||
_o.call(this, i, addition[i]);
|
||||
} else {
|
||||
this[i] = addition[i];
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/** The overload() method overloads a single method in an object; it
|
||||
* creates a new function that sets this.base to the old value then
|
||||
* calls the new code.
|
||||
* @param name the name of the method to be overloaded.
|
||||
* @param value the Function object for the new method.
|
||||
* @returns the value for the overloaded method.
|
||||
*/
|
||||
overload: function (name, value) {
|
||||
if (value == this[name] || name == 'base') {
|
||||
return;
|
||||
}
|
||||
|
||||
var _v = value, _ov = this[name];
|
||||
value = function () {
|
||||
var _b = this.base;
|
||||
this.base = _ov;
|
||||
var _r = _v.apply(this, arguments);
|
||||
this.base = _b;
|
||||
return _r;
|
||||
};
|
||||
value.valueOf = function() {
|
||||
return _v;
|
||||
};
|
||||
value.toString = function () {
|
||||
return String(_v);
|
||||
};
|
||||
|
||||
return this[name] = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** This class property stores the list of namespaces to preserve when onunload is called. */
|
||||
Base._preserve = new Array();
|
||||
|
||||
|
||||
/** This static method is used to define class inheritance.
|
||||
* @param members an object containing the new methods and properties to be added or overloaded.
|
||||
* @param cMembers an object containing the methods and properties to be added as static members.
|
||||
* @param name a string indicating the namespace this object is supposed to define; it is used
|
||||
* to preserve namespaces from being deleted before the onunload() handler.
|
||||
* @return the object corresponding to the newly created class.
|
||||
*/
|
||||
Base.inherits = function (members, cMembers, name) {
|
||||
if (!members) {
|
||||
members = { };
|
||||
}
|
||||
|
||||
var _e = Base.prototype.extend;
|
||||
var _b = this;
|
||||
|
||||
Base._inherits = true;
|
||||
var _p = new _b;
|
||||
_e.call(_p, members);
|
||||
delete Base._inherits;
|
||||
|
||||
var _c = _p.constructor;
|
||||
_p.constructor = this;
|
||||
|
||||
var _cl = function() {
|
||||
this.base = _b;
|
||||
if (!Base._inherits) {
|
||||
_c.apply(this, arguments);
|
||||
}
|
||||
this.constructor = _cl;
|
||||
delete this.base;
|
||||
};
|
||||
_cl.inherits = this.inherits;
|
||||
_cl.toString = function() {
|
||||
return String(_c);
|
||||
};
|
||||
_cl.prototype = _p;
|
||||
|
||||
if (!cMembers) {
|
||||
cMembers = { };
|
||||
}
|
||||
_e.call(_cl, cMembers);
|
||||
|
||||
if (cMembers["onLoad"] instanceof Function) {
|
||||
Base.registerInitialiser(_cl["onLoad"]);
|
||||
}
|
||||
if (cMembers["onUnload"] instanceof Function) {
|
||||
Base.registerDestructor(_cl["onUnload"]);
|
||||
}
|
||||
|
||||
if (name && name != "") {
|
||||
Base._preserve[name] = _cl;
|
||||
}
|
||||
|
||||
return _cl;
|
||||
};
|
||||
|
||||
|
||||
/** Set the page's onload() handler. */
|
||||
window.onload = function () {
|
||||
var _b = Base;
|
||||
for (var i in _b.initialisers) {
|
||||
if (typeof _b.initialisers[i] == 'undefined') {
|
||||
continue;
|
||||
}
|
||||
_b.initialisers[i]();
|
||||
}
|
||||
|
||||
/** Set the page's onunload() handler. */
|
||||
window.onunload = function () {
|
||||
Base = _b;
|
||||
for (var i in _b._preserve) {
|
||||
eval(i + " = _b._preserve[i]");
|
||||
}
|
||||
|
||||
for (var i = _b.destructors.length - 1; i >= 0; i--) {
|
||||
_b.destructors[i]();
|
||||
}
|
||||
};
|
||||
};
|
|
@ -1,94 +0,0 @@
|
|||
/** The Base.Browser class contains the code that detects the user's browser and keeps
|
||||
* track of the current window's size.
|
||||
*/
|
||||
Base.Browser = Base.Comp.inherits({
|
||||
|
||||
/** The constructor detects the browser type, then initialises the window size
|
||||
* watching code.
|
||||
*/
|
||||
constructor: function () {
|
||||
if (Base.Browser.singleton) {
|
||||
throw "SingletonException";
|
||||
}
|
||||
|
||||
this.base();
|
||||
|
||||
// Get the document body object
|
||||
this.docBody = (document.compatMode && document.compatMode != 'BackCompat') ? document.documentElement : (document.body ? document.body : null);
|
||||
|
||||
// Detect the browser's type
|
||||
var nav = navigator.userAgent.toLowerCase(), ver = navigator.appVersion;
|
||||
this.opera = window.opera && document.getElementById;
|
||||
this.ie = nav.indexOf("msie") != -1 && document.all && this.docBody && !this.opera;
|
||||
this.opera6 = this.opera && !document.defaultView;
|
||||
this.operaOther = this.opera && !this.opera6;
|
||||
this.ie7 = this.ie && parseFloat(ver.substring(ver.indexOf("MSIE")+5)) >= 7;
|
||||
this.ie6 = this.ie && !this.ie7 && parseFloat(ver.substring(ver.indexOf("MSIE")+5)) >= 5.5;
|
||||
var ns = !this.opera && document.defaultView && (typeof document.defaultView.getComputedStyle != "undefined");
|
||||
this.konqueror = ns && nav.indexOf('konqueror') != -1;
|
||||
this.safari = ns && nav.indexOf('applewebkit') != -1;
|
||||
this.ns6 = ns && !this.konqueror && !this.safari;
|
||||
this.supported = this.docBody && (this.ie6 || this.ie7 || this.opera || this.ns6 || this.konqueror || this.safari);
|
||||
|
||||
// Prepare the window size watching code
|
||||
this.addEvent('SizeChanged');
|
||||
var _cid = this._cid;
|
||||
window.onresize = function () {
|
||||
Base.Comp.get(_cid).handleResize();
|
||||
};
|
||||
if (this.konqueror) {
|
||||
this.addSlot('resizeTimer');
|
||||
this.timer = new Base.Timer(250, false);
|
||||
this.timer.bindEvent('Tick', 'resizeTimer', this);
|
||||
}
|
||||
this.readSize();
|
||||
},
|
||||
|
||||
/** This method reads the current window's size.
|
||||
*/
|
||||
readSize: function () {
|
||||
this.width = (this.ie ? this.docBody.offsetWidth : window.innerWidth);
|
||||
this.height = (this.ie ? this.docBody.offsetHeight : window.innerHeight);
|
||||
},
|
||||
|
||||
/** This method is called by the resize handler or, if the user is running Konqueror,
|
||||
* by the timer that keeps track of resizing. It reads the current size, and if that
|
||||
* size is different from the old size, it sends a SizeChanged(width,height) event.
|
||||
*/
|
||||
resizeTimer: function () {
|
||||
var ow = this.width, oh = this.height;
|
||||
this.readSize();
|
||||
if (ow != this.width || oh != this.height) {
|
||||
this.onSizeChanged(this.width, this.height);
|
||||
}
|
||||
},
|
||||
|
||||
/** This method either forces the object to re-check the window's size or, if the
|
||||
* user is running Konqueror, starts or restarts the update timer to prevent
|
||||
* receiving multiple window update codes.
|
||||
*/
|
||||
handleResize: function () {
|
||||
if (this.konqueror) {
|
||||
this.timer.restart();
|
||||
return;
|
||||
}
|
||||
this.resizeTimer();
|
||||
}
|
||||
|
||||
}, {
|
||||
|
||||
/** This class property contains the single Base.Browser instance.
|
||||
*/
|
||||
singleton: null,
|
||||
|
||||
/** This class method returns the Base.Browser instance after creating it
|
||||
* if it didn't exist.
|
||||
*/
|
||||
get: function () {
|
||||
if (!Base.Browser.singleton) {
|
||||
Base.Browser.singleton = new Base.Browser();
|
||||
}
|
||||
return Base.Browser.singleton;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,217 +0,0 @@
|
|||
/** The Base.Comp class is the base class for all of the components. It provides the
|
||||
* signal/slot framework that the components use, and allows access to components using
|
||||
* their unique identifier.
|
||||
*/
|
||||
Base.Comp = Base.inherits({
|
||||
|
||||
/** The constructor initialises the component by assigning its identifier, creating the
|
||||
* tables listing the slots, events and children, and creating the low-level slots and
|
||||
* events common to all components.
|
||||
*/
|
||||
constructor: function () {
|
||||
this._cid = ++ Base.Comp.lastId;
|
||||
this._slots = new Base.Util.Hashtable();
|
||||
this._evts = new Base.Util.Hashtable();
|
||||
this._chld = new Base.Util.Hashtable();
|
||||
this._cnt = null;
|
||||
|
||||
Base.Comp.list.put(this._cid, this);
|
||||
Base.Comp.count ++;
|
||||
|
||||
this.destroyChildren = false;
|
||||
|
||||
this.addEvent('Destroy');
|
||||
this.addSlot('addChild');
|
||||
this.addSlot('removeChild');
|
||||
},
|
||||
|
||||
/** This method is responsible for the destruction of a component. It
|
||||
* starts by launching the onDestroy() event; it then detaches the
|
||||
* component's children (or destroy them if the destroyChildren member
|
||||
* is set to true), then detaches all of the component's slots and
|
||||
* events. Finally, it removes the reference to the component in the
|
||||
* global components list.
|
||||
*/
|
||||
destroy: function () {
|
||||
this.onDestroy(this._cid);
|
||||
|
||||
var k = this._chld.keys();
|
||||
for (var i in k) {
|
||||
var c = this._chld.get(k[i]);
|
||||
if (this.destroyChildren) {
|
||||
c.destroy();
|
||||
} else {
|
||||
this.removeChild(c);
|
||||
}
|
||||
}
|
||||
|
||||
k = this._slots.keys();
|
||||
for (var i in k) {
|
||||
this._slots.get(k[i]).destroy();
|
||||
}
|
||||
this._slots.clear();
|
||||
|
||||
k = this._evts.keys();
|
||||
for (var i in k) {
|
||||
this._evts.get(k[i]).destroy();
|
||||
}
|
||||
this._evts.clear();
|
||||
|
||||
Base.Comp.list.remove(this._cid);
|
||||
Base.Comp.count --;
|
||||
|
||||
for (var i in this) {
|
||||
this[i] = null;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/** This method declares a new slot for the current component.
|
||||
* @param name the name of the slot to be declared
|
||||
*/
|
||||
addSlot: function (name) {
|
||||
if (this._slots.containsKey(name) || !this[name]) {
|
||||
return;
|
||||
}
|
||||
this._slots.put(name, new Base.Comp.Slot(name, this));
|
||||
},
|
||||
|
||||
/** This method generates a new event handler for the current component.
|
||||
* @param name the name of the event to create
|
||||
* @param propagate a boolean indicating the event propagates to the component's children
|
||||
*/
|
||||
addEvent: function (name, propagate) {
|
||||
if (this._evts.containsKey(name) || this["on" + name]) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._evts.put(name, new Base.Comp.Evt(name, propagate));
|
||||
this["on" + name] = function() {
|
||||
this.triggerEvent(name, arguments);
|
||||
};
|
||||
this.addSlot('on' + name);
|
||||
},
|
||||
|
||||
|
||||
/** This method binds an event from the current component to a slot on either the current
|
||||
* component or, if the last parameter is present, another component.
|
||||
* @param eName the name of the event to bind
|
||||
* @param sName the name of the slots to bind an event to
|
||||
* @param cmp the component on which to bind (if this parameter isn't passed, the current component is used)
|
||||
*/
|
||||
bindEvent: function (eName, sName, cmp) {
|
||||
var e = this._evts.get(eName), c = (cmp ? cmp : this), s = c._slots.get(sName);
|
||||
if (!(e && s)) {
|
||||
return;
|
||||
}
|
||||
e.bind(s);
|
||||
},
|
||||
|
||||
/** This method detaches an event from the current component from a slot to which it had been bound.
|
||||
* @param eName the name of the event to detach
|
||||
* @param sName the name of the slot to detach
|
||||
* @param cmp the component on which the slot to detach is located
|
||||
*/
|
||||
detachEvent: function (eName, sName, cmp) {
|
||||
var e = this._evts.get(eName), c = (cmp ? cmp : this), s = c._slots.get(sName);
|
||||
if (!(e && s)) {
|
||||
return;
|
||||
}
|
||||
e.detach(s);
|
||||
},
|
||||
|
||||
|
||||
/** This method triggers the execution of an event on the current component.
|
||||
* @param eName the name of the event to trigger
|
||||
* @param args an array containing the arguments to be passed to the event's handlers
|
||||
*/
|
||||
triggerEvent: function (eName, args) {
|
||||
var e = this._evts.get(eName);
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.trigger.apply(e, args);
|
||||
|
||||
if (!e.propagate) {
|
||||
return;
|
||||
}
|
||||
|
||||
var k = this._chld.keys();
|
||||
for (i=0;i<k.length;i++) {
|
||||
this._chld.get(k[i]).triggerEvent(eName, args);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/** This method adds a child to the current component.
|
||||
* @param cmp the component to add as a child of the current component
|
||||
*/
|
||||
addChild: function (cmp) {
|
||||
if (!cmp || cmp._cid == this._cid || cmp.container != null) {
|
||||
return;
|
||||
}
|
||||
cmp.container = this;
|
||||
this._chld.put(cmp._cid, cmp);
|
||||
cmp.bindEvent('Destroy', 'removeChild', this);
|
||||
},
|
||||
|
||||
/** This method removes a child from the current component's list of children.
|
||||
* @param cmp the child component to remove
|
||||
*/
|
||||
removeChild: function (cmp) {
|
||||
if (!(cmp && this._chld.containsKey(cmp._cid))) {
|
||||
return;
|
||||
}
|
||||
this._chld.remove(cmp._cid);
|
||||
cmp.container = null;
|
||||
cmp.detachEvent('Destroy', 'removeChild', this);
|
||||
},
|
||||
|
||||
/** This method checks whether a component is a child of the current component.
|
||||
* @param cmp the component to verify
|
||||
* @returs true if the specified component is a child of the current component, false otherwise
|
||||
*/
|
||||
hasChild: function (cmp) {
|
||||
return (cmp && cmp.container && cmp.container._cid == this._cid);
|
||||
}
|
||||
|
||||
}, {
|
||||
|
||||
/** This class property contains the list of all available components;
|
||||
* the components' identifiers are used as the key.
|
||||
*/
|
||||
list: new Base.Util.Hashtable(),
|
||||
|
||||
/** This class property stores the last identifier assigned to a
|
||||
* component.
|
||||
*/
|
||||
lastId: -1,
|
||||
|
||||
/** This class property stores the amount of components currently
|
||||
* being used.
|
||||
*/
|
||||
count: 0,
|
||||
|
||||
/** This static method returns a component from its identifier.
|
||||
* @param id the component's identifier
|
||||
*/
|
||||
get: function (id) {
|
||||
if (!Base.Comp.list.containsKey(id)) {
|
||||
return null;
|
||||
}
|
||||
return Base.Comp.list.get(id);
|
||||
},
|
||||
|
||||
/** This static method destroys all of the components.
|
||||
*/
|
||||
onUnload: function () {
|
||||
var l = Base.Comp.list.values();
|
||||
for (var i in l) {
|
||||
if (l[i] && l[i].destroy) {
|
||||
l[i].destroy();
|
||||
}
|
||||
}
|
||||
Base.Comp.list.clear();
|
||||
}
|
||||
});
|
|
@ -1,77 +0,0 @@
|
|||
/** This class defines the data structure and operations required to handle a component's
|
||||
* events.
|
||||
*/
|
||||
Base.Comp.Evt = Base.inherits({
|
||||
|
||||
/** The constructor generates an event storage for an event on a component's
|
||||
* instance.
|
||||
* @param name the name of the event
|
||||
* @param propagate a boolean indicating whether this event should
|
||||
* be propagated to a component's children
|
||||
*/
|
||||
constructor: function (name, propagate) {
|
||||
this.id = ++Base.Comp.Evt.lId;
|
||||
this.name = name;
|
||||
this.propagate = propagate;
|
||||
this.bindings = new Base.Util.Hashtable();
|
||||
|
||||
Base.Comp.Evt.list[this.id] = this;
|
||||
},
|
||||
|
||||
/** This method is responsible for cleaning up an event storage instance being
|
||||
* destroyed.
|
||||
*/
|
||||
destroy: function () {
|
||||
var k = this.bindings.keys(), i;
|
||||
for (i=0;i<k.length;i++) {
|
||||
var s = this.bindings.get(k[i]);
|
||||
s.events.remove(this.id);
|
||||
this.bindings.remove(s.id);
|
||||
}
|
||||
|
||||
Base.Comp.Evt.list[this.id] = null;
|
||||
for (var i in this) {
|
||||
this[i] = null;
|
||||
}
|
||||
},
|
||||
|
||||
/** This method binds the current event to a specified slot.
|
||||
* @param slot the slot to which the event will be bound
|
||||
*/
|
||||
bind: function (slot) {
|
||||
if (slot && !this.bindings.containsKey(slot.id) && !slot.events.containsKey(this.id)) {
|
||||
slot.events.put(this.id, this);
|
||||
this.bindings.put(slot.id, slot);
|
||||
}
|
||||
},
|
||||
|
||||
/** This method detaches the current event from a specified slot.
|
||||
* @param slot the slot from which the event should be detached
|
||||
*/
|
||||
detach: function (slot) {
|
||||
if (slot && this.bindings.containsKey(slot.id) && slot.events.containsKey(this.id)) {
|
||||
slot.events.remove(this.id);
|
||||
this.bindings.remove(slot.id);
|
||||
}
|
||||
},
|
||||
|
||||
/** This method triggers the execution of all the slots bound to the event.
|
||||
*/
|
||||
trigger: function() {
|
||||
var i, k = this.bindings.keys();
|
||||
for (i=0;i<k.length;i++) {
|
||||
this.bindings.get(k[i]).call(arguments);
|
||||
}
|
||||
}
|
||||
|
||||
}, {
|
||||
|
||||
/** This class property stores the value of the last attributed event identifier.
|
||||
*/
|
||||
lId: -1,
|
||||
|
||||
/** This class property stores the list of all existing events.
|
||||
*/
|
||||
list: new Array()
|
||||
|
||||
});
|
|
@ -1,50 +0,0 @@
|
|||
/** This class defines the data structure and operations required to handle a component's
|
||||
* slots.
|
||||
*/
|
||||
Base.Comp.Slot = Base.inherits({
|
||||
|
||||
/** The constructor generates a new slot bound to a specified component.
|
||||
* @param name the slot's name
|
||||
* @param component the component instance to which this slot belongs
|
||||
*/
|
||||
constructor: function (name, component) {
|
||||
this.id = ++Base.Comp.Slot.lId;
|
||||
this.name = name;
|
||||
this.component = component;
|
||||
this.events = new Base.Util.Hashtable();
|
||||
},
|
||||
|
||||
/** This method calls the component's method for the slot the current instance
|
||||
* represents.
|
||||
* @param a an array containing the parameters to be passed to the
|
||||
* component's method.
|
||||
*/
|
||||
call: function(a) {
|
||||
this.component[this.name].apply(this.component, a);
|
||||
},
|
||||
|
||||
/** This method destroys a slot.
|
||||
*/
|
||||
destroy: function () {
|
||||
var k = this.events.keys(), i;
|
||||
for (i=0;i<k.length;i++) {
|
||||
this.events.get(k[i]).detach(this);
|
||||
}
|
||||
|
||||
Base.Comp.Slot.list[this.id] = null;
|
||||
for (var i in this) {
|
||||
this[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
}, {
|
||||
|
||||
/** This class property contains the last attributed slot identifier.
|
||||
*/
|
||||
lId: -1,
|
||||
|
||||
/** This class property contains the list of all existing slots.
|
||||
*/
|
||||
list: new Array()
|
||||
|
||||
});
|
|
@ -1,52 +0,0 @@
|
|||
Base.Log = Base.inherits({
|
||||
|
||||
constructor: function (maxSize) {
|
||||
this.base();
|
||||
this.log = new Array();
|
||||
this.maxSize = maxSize ? maxSize : 4096;
|
||||
},
|
||||
|
||||
insert: function (line) {
|
||||
if (!line) {
|
||||
return;
|
||||
}
|
||||
if (this.log.length == this.maxSize) {
|
||||
this.log.shift();
|
||||
}
|
||||
this.log.push(line);
|
||||
},
|
||||
|
||||
flush: function () {
|
||||
this.log = new Array();
|
||||
}
|
||||
|
||||
}, {
|
||||
|
||||
singleton: null,
|
||||
|
||||
initLog: function (maxSize) {
|
||||
if (!this.singleton) {
|
||||
this.singleton = new this(maxSize);
|
||||
}
|
||||
},
|
||||
|
||||
write: function (line) {
|
||||
if (this.singleton) {
|
||||
this.singleton.insert(line);
|
||||
}
|
||||
},
|
||||
|
||||
get: function () {
|
||||
return (this.singleton ? this.singleton.log : new Array());
|
||||
},
|
||||
|
||||
flush: function () {
|
||||
if (!this.singleton) {
|
||||
return new Array();
|
||||
}
|
||||
var _r = this.singleton.log;
|
||||
this.singleton.flush();
|
||||
return _r;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,169 +0,0 @@
|
|||
Base.Timer = Base.Comp.inherits({
|
||||
|
||||
/** This property contains the setTimeout() result value being used for the
|
||||
* timer.
|
||||
*/
|
||||
timer: null,
|
||||
|
||||
/** This property contains the timestamp of the last executed tick.
|
||||
*/
|
||||
lastAt: 0,
|
||||
|
||||
/** This property contains the timestamp at which the timer was paused.
|
||||
*/
|
||||
pausedAt: 0,
|
||||
|
||||
/** This property is used internally to lock access to the instance's
|
||||
* properties.
|
||||
*/
|
||||
locked: false,
|
||||
|
||||
/** This property indicates whether the timer is currently running.
|
||||
*/
|
||||
running: false,
|
||||
|
||||
|
||||
/** The constructor initialises a new timer instance. It does not start
|
||||
* the timer, however - the start() method has to be called.
|
||||
* @param miliseconds the interval for the timer, in milliseconds
|
||||
* @param repeat a boolean indicating whether the timer fires
|
||||
* only once (false) or repeatedly (true)
|
||||
*/
|
||||
constructor: function (miliseconds, repeat) {
|
||||
this.base();
|
||||
|
||||
this.addSlot('start');
|
||||
this.addSlot('stop');
|
||||
this.addSlot('restart');
|
||||
this.addSlot('pause');
|
||||
|
||||
this.addEvent('Tick');
|
||||
|
||||
this.miliseconds = miliseconds;
|
||||
this.repeat = repeat;
|
||||
},
|
||||
|
||||
/** This method stops the timer then destroys the instance.
|
||||
*/
|
||||
destroy: function () {
|
||||
while (this.locked) ;
|
||||
this.locked = true;
|
||||
|
||||
if (this.running) {
|
||||
clearTimeout(this.timer);
|
||||
this.lastAt = this.pausedAt = 0;
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
this.base();
|
||||
},
|
||||
|
||||
|
||||
/** This method initialises the timer itself.
|
||||
*/
|
||||
start: function() {
|
||||
while (this.locked) ;
|
||||
this.locked = true;
|
||||
|
||||
if (!this.running) {
|
||||
this.running = true;
|
||||
this.lastAt = new Date().getTime();
|
||||
this.setTimer();
|
||||
}
|
||||
|
||||
this.locked = false;
|
||||
},
|
||||
|
||||
/** This method stops the timer from running.
|
||||
*/
|
||||
stop: function() {
|
||||
while (this.locked) ;
|
||||
this.locked = true;
|
||||
|
||||
if (this.running) {
|
||||
clearTimeout(this.timer);
|
||||
this.lastAt = this.pausedAt = 0;
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
this.locked = false;
|
||||
},
|
||||
|
||||
/** This method restarts the timer. It is equivalent to calling
|
||||
* stop() then start(), but it is faster.
|
||||
*/
|
||||
restart: function() {
|
||||
while (this.locked) ;
|
||||
this.locked = true;
|
||||
|
||||
if (this.running) {
|
||||
clearTimeout(this.timer);
|
||||
this.pausedAt = 0;
|
||||
} else {
|
||||
this.running = true;
|
||||
}
|
||||
this.lastAt = new Date().getTime();
|
||||
this.setTimer();
|
||||
this.locked = false;
|
||||
},
|
||||
|
||||
/** This method puts the timer on pause if it is currently running or
|
||||
* restarts it if it had been paused earlier.
|
||||
*/
|
||||
pause: function () {
|
||||
while (this.locked) ;
|
||||
this.locked = true;
|
||||
|
||||
if (this.running) {
|
||||
if (this.pausedAt == 0) {
|
||||
this.pausedAt = new Date().getTime();
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
}
|
||||
} else {
|
||||
this.setTimer();
|
||||
this.pausedAt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
this.locked = false;
|
||||
},
|
||||
|
||||
|
||||
/** This method is called automatically by the setTimeout() timer; if
|
||||
* the current instance is still supposed to be running, it will:
|
||||
* - re-run setTimeout() to initialise the next tick if the timer is
|
||||
* in "repeat" mode,
|
||||
* - trigger the Tick event.
|
||||
*/
|
||||
tick: function() {
|
||||
while (this.locked) ;
|
||||
this.locked = true;
|
||||
|
||||
var re;
|
||||
if (re = (this.running && !this.pausedAt)) {
|
||||
if (this.repeat) {
|
||||
this.lastAt = new Date().getTime();
|
||||
this.setTimer();
|
||||
} else {
|
||||
this.running = false;
|
||||
this.timer = null;
|
||||
this.lastAt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
this.locked = false;
|
||||
|
||||
if (re) {
|
||||
this.onTick();
|
||||
}
|
||||
},
|
||||
|
||||
/** This method is used internally in order to run setTimeout() with
|
||||
* the required parameters.
|
||||
*/
|
||||
setTimer: function() {
|
||||
var _t = this.pausedAt ? (this.miliseconds - this.pausedAt + this.lastAt) : this.miliseconds;
|
||||
this.timer = setTimeout("Base.Comp.get(" + this._cid + ").tick()", _t);
|
||||
}
|
||||
});
|
|
@ -1,95 +0,0 @@
|
|||
/** The Base.Util class provide a few utility functions such as number formatting. */
|
||||
Base.Util = Base.inherits(null, {
|
||||
|
||||
/** This class property is used on IE to determine which type of ActiveX object
|
||||
* the current version uses, depending on the amount of frogs that fell from the
|
||||
* sky and the amount of hairs under my armpits at this time.
|
||||
*/
|
||||
_ieXMLParser: null,
|
||||
|
||||
/** The formatNumber() method transforms an integer into a string in which
|
||||
* the integer has commas between each group of thousands.
|
||||
* @param n the value to be formatted
|
||||
*/
|
||||
formatNumber: function (n) {
|
||||
var x = parseInt(n, 10);
|
||||
if (isNaN(x)) {
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
if (x < 0) {
|
||||
x = -x;
|
||||
s = '-';
|
||||
} else {
|
||||
s = '';
|
||||
}
|
||||
x = x.toString();
|
||||
|
||||
var l = x.length, m = l % 3, c = (l - m) / 3, v = ((m > 0) ? x.substr(0, m) : ''), z;
|
||||
for (z=0;z<c;z++) {
|
||||
if (v != "" && v != '-') {
|
||||
v += ',';
|
||||
}
|
||||
v += x.substr(m+(z*3), 3);
|
||||
}
|
||||
return s + v;
|
||||
},
|
||||
|
||||
|
||||
/** This method parses an XML document using the brower-supplied DOM parser.
|
||||
* @param text the XML data to be parsed
|
||||
* @returns the boolean value "false" on failure or the DOM document on
|
||||
* success
|
||||
*/
|
||||
parseXML: function (text) {
|
||||
var xmlDoc;
|
||||
try {
|
||||
if (Base.Browser.get().ie) {
|
||||
if (!this._ieXMLParser) {
|
||||
this._checkIEXMLParser();
|
||||
}
|
||||
|
||||
xmlDoc = new ActiveXObject(this._ieXMLParser);
|
||||
xmlDoc.async = "false";
|
||||
xmlDoc.loadXML(text);
|
||||
} else {
|
||||
var parser = new DOMParser();
|
||||
xmlDoc = parser.parseFromString(text, "text/xml");
|
||||
}
|
||||
} catch (e) {
|
||||
Base.Log.write('Base.Util.parseXML(): failed with exception ' + (e.toString ? e.toString() : e));
|
||||
xmlDoc = false;
|
||||
}
|
||||
|
||||
return xmlDoc;
|
||||
},
|
||||
|
||||
|
||||
/** This class method is used by the parseXML() method to check on known XML parsers
|
||||
* when running IE. It throws a random exception if none of the listed implementations
|
||||
* actually exist.
|
||||
*/
|
||||
_checkIEXMLParser: function () {
|
||||
var impls = [
|
||||
"Msxml2.DOMDocument.7.0", "Msxml2.DOMDocument.6.0",
|
||||
"Msxml2.DOMDocument.5.0", "Msxml2.DOMDocument.4.0",
|
||||
"Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument",
|
||||
"MSXML.DOMDocument", "Microsoft.XMLDOM"
|
||||
];
|
||||
|
||||
for (var i in impls) {
|
||||
try {
|
||||
new ActiveXObject(impls[i]);
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
this._ieXMLParser = impls[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if (!this._ieXMLParser) {
|
||||
throw "IEWithoutXMLParser";
|
||||
}
|
||||
}
|
||||
|
||||
});
|
|
@ -1,125 +0,0 @@
|
|||
/** The Base.Util.Hashtable class allows manipulation of hashtables by encapsulating a
|
||||
* JavaScript array and using it to store the data.
|
||||
*/
|
||||
Base.Util.Hashtable = Base.inherits({
|
||||
|
||||
/** The constructor initialises the array used to store the hashtable.
|
||||
*/
|
||||
constructor: function () {
|
||||
this.hashtable = new Array();
|
||||
},
|
||||
|
||||
/** The clear() method reinitialises the hashtable. */
|
||||
clear: function () {
|
||||
this.hashtable = new Array();
|
||||
},
|
||||
|
||||
/** The get() method returns the value associated with a specified key.
|
||||
* @param key the key for which the value must be returned
|
||||
* @returns the value associated with the key or undefined/null if none was found
|
||||
*/
|
||||
get: function (key) {
|
||||
return this.hashtable[key];
|
||||
},
|
||||
|
||||
/** This method indicates whether the hashtable contains items or not.
|
||||
* @returns true if the table is empty, false otherwise
|
||||
*/
|
||||
isEmpty: function () {
|
||||
return (parseInt(this.size()) == 0);
|
||||
},
|
||||
|
||||
/** This method indicates whether the hashtable contains a specified key or not.
|
||||
* @param key the key to look up in the table
|
||||
* @return true if a value is associated with the specified key, false otherwise
|
||||
*/
|
||||
containsKey: function (key) {
|
||||
var exists = false;
|
||||
for (var i in this.hashtable) {
|
||||
if (i == key && this.hashtable[i] != null) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return exists;
|
||||
},
|
||||
|
||||
/** This method checks whether a specific value is stored within the hashtable.
|
||||
* @param value the value to search for
|
||||
* @return true if the value was found, false otherwise
|
||||
*/
|
||||
containsValue: function (value) {
|
||||
var contains = false;
|
||||
if (value != null) {
|
||||
for (var i in this.hashtable) {
|
||||
if (this.hashtable[i] == value) {
|
||||
contains=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return contains;
|
||||
},
|
||||
|
||||
/** This method returns an array containing all of the hashtable's keys to which a
|
||||
* value has been associated.
|
||||
* @returns the array containing all of the table's keys
|
||||
*/
|
||||
keys: function () {
|
||||
var keys=new Array();
|
||||
for (var i in this.hashtable) {
|
||||
if (this.hashtable[i] != null) {
|
||||
keys.push(i);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
},
|
||||
|
||||
/** This method returns an array containing all of the values stored within the
|
||||
* hashtable.
|
||||
* @returns the array containing all of the table's values
|
||||
*/
|
||||
values: function () {
|
||||
var values = new Array();
|
||||
for (var i in this.hashtable) {
|
||||
if (this.hashtable[i] != null) {
|
||||
values.push(this.hashtable[i]);
|
||||
}
|
||||
}
|
||||
return values;
|
||||
},
|
||||
|
||||
/** This method stores a value in the table, associating it with the specified key.
|
||||
* If a value was already associated with the specified key, it is overwritten.
|
||||
* @param key the key to which the value is to be associated.
|
||||
* @param value the value to store
|
||||
*/
|
||||
put: function (key, value) {
|
||||
if (key == null || value == null) {
|
||||
throw "NullPointerException {"+key+"},{"+value+"}";
|
||||
}
|
||||
this.hashtable[key] = value;
|
||||
},
|
||||
|
||||
/** This method removes an association from the table.
|
||||
* @param key the key for the association to be removed
|
||||
*/
|
||||
remove: function (key) {
|
||||
var rtn = this.hashtable[key];
|
||||
this.hashtable[key] = null;
|
||||
return rtn;
|
||||
},
|
||||
|
||||
/** This method computes the amount of associations currently stored in the table.
|
||||
* @returns the amount of associations
|
||||
*/
|
||||
size: function () {
|
||||
var size = 0;
|
||||
for (var i in this.hashtable) {
|
||||
if (this.hashtable[i] != null) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
});
|
|
@ -1,313 +0,0 @@
|
|||
/** This class allows the user to load data files from the server using the browser's
|
||||
* native XML loader class.
|
||||
*/
|
||||
Base.XMLLoader = Base.Comp.inherits({
|
||||
|
||||
/** This property indicates whether the instance is currently loading data
|
||||
* from the server.
|
||||
*/
|
||||
isLoading: false,
|
||||
|
||||
/** This property contains the native XML loader object when data is being
|
||||
* loaded or null when the loader isn't active.
|
||||
*/
|
||||
xmlObject: null,
|
||||
|
||||
/** This property contains the loader's timer when data is being retrieved.
|
||||
* The timer will be used to force the loader object to timeout. When no
|
||||
* data is being loaded, the property contains the null value.
|
||||
*/
|
||||
timer: null,
|
||||
|
||||
|
||||
/** The constructor initialises the component itself and sets default values
|
||||
* for the URI, method and timeout to use.
|
||||
* @param uri a string containing the URI from which the data is
|
||||
* to be fetched
|
||||
* @param usePost a boolean indicating whether the loader should use
|
||||
* the HTTP POST method (true) or GET method
|
||||
* @param timeout an optionnal integer containing the amount of seconds
|
||||
* before the loader times out; this defaults to
|
||||
* 20 seconds if the parameter is missing
|
||||
*/
|
||||
constructor: function (uri, usePost, timeout) {
|
||||
this.base();
|
||||
|
||||
this.addEvent('Aborted');
|
||||
this.addEvent('Loaded');
|
||||
this.addEvent('NetworkError');
|
||||
this.addEvent('ServerError');
|
||||
this.addEvent('Timeout');
|
||||
this.addEvent('Unsupported');
|
||||
|
||||
this.addSlot('load');
|
||||
this.addSlot('abort');
|
||||
this.addSlot('timedOut');
|
||||
|
||||
this.uri = uri;
|
||||
this.usePost = usePost;
|
||||
this.timeout = timeout ? timeout : 20;
|
||||
},
|
||||
|
||||
/** The destructor starts by aborting the loader's operation, then calls
|
||||
* the standard component destructor.
|
||||
*/
|
||||
destroy: function () {
|
||||
this.abort();
|
||||
this.base();
|
||||
},
|
||||
|
||||
|
||||
/** This method allows the user to change the parameters such as the URI, the
|
||||
* method to be used and the timeout value. It will only be able to do so if
|
||||
* the loader isn't operating.
|
||||
* @param uri the new data URI (ignored if null)
|
||||
* @param usePost the new method to use (ignored if null)
|
||||
* @param timeout the new value for the loader's timeout (ignored if
|
||||
* null)
|
||||
* @returns true if the values were set, false if they weren't
|
||||
*/
|
||||
changeParameters: function (uri, usePost, timeout) {
|
||||
if (this.isLoading) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.uri = uri ? uri : this.uri;
|
||||
this.usePost = (typeof usePost == 'boolean') ? usePost : this.usePost;
|
||||
this.timeout = timeout ? timeout : 20;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
/** This method loads the data using the object's URI and method using the
|
||||
* specified parameters.
|
||||
* @param parameters a hashtable associating to each of the parameters'
|
||||
* name a value that is either a string or an
|
||||
* array
|
||||
* @returns true if the loader was successfully started
|
||||
*/
|
||||
load: function (parameters) {
|
||||
// Make sure we're not already loading
|
||||
if (this.isLoading) {
|
||||
return false;
|
||||
}
|
||||
this.isLoading = true;
|
||||
Base.Log.write('Base.XMLLoader.load(): ' + (this.usePost ? 'POST' : 'GET') + ' ' + this.uri);
|
||||
|
||||
// Initialise the native loader object
|
||||
var obj = Base.XMLLoader.makeNativeInstance();
|
||||
if (!obj) {
|
||||
this.isLoading = false;
|
||||
Base.Log.write('Base.XMLLoader.load(): XMLHttpRequest unsupported');
|
||||
this.onUnsupported();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate the parameters string and the URI
|
||||
var uri = this.uri, ps;
|
||||
if (parameters) {
|
||||
ps = Base.XMLLoader.encodeParameters(parameters);
|
||||
if (!this.usePost) {
|
||||
uri += '?' + ps;
|
||||
}
|
||||
} else {
|
||||
ps = "";
|
||||
}
|
||||
|
||||
/*
|
||||
// Safari and IE are stupid
|
||||
if (Base.Browser.get().safari || Base.Browser.get().IE) {
|
||||
if (this.usePost || ps == '') {
|
||||
uri += '?stoopid_browsa=' + (new Date()).getTime();
|
||||
} else {
|
||||
uri += '&stoopid_browsa=' + (new Date()).getTime();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Get ready to send the request
|
||||
try {
|
||||
obj.open(this.usePost ? "POST" : "GET", uri, true);
|
||||
} catch (e) {
|
||||
// We got a permission problem
|
||||
this.isLoading = false;
|
||||
Base.Log.write('Base.XMLLoader.load(): XMLHttpRequest.open() failed, possible permission problem');
|
||||
Base.Log.write('Base.XMLLoader.load(): exception was ' + (e.toString ? e.toString() : e));
|
||||
this.onUnsupported();
|
||||
return false;
|
||||
}
|
||||
if (this.usePost) {
|
||||
obj.setRequestHeader("Method", "POST " + uri + " HTTP/1.1");
|
||||
obj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
}
|
||||
// Safari is still stupid
|
||||
if (Base.Browser.get().safari) {
|
||||
obj.setRequestHeader('If-Modified-Since', 'Wed, 15 Nov 1995 00:00:00 GMT');
|
||||
obj.setRequestHeader("Cache-Control", "no-cache");
|
||||
}
|
||||
|
||||
// Initialise the timer
|
||||
this.timer = new Base.Timer(this.timeout * 1000);
|
||||
this.timer.bindEvent('Tick', 'timedOut', this);
|
||||
|
||||
// Prepare the callback
|
||||
var _id = this._cid;
|
||||
obj.onreadystatechange = function () {
|
||||
if (typeof Base != 'undefined') {
|
||||
Base.Comp.get(_id).loaderEvent();
|
||||
}
|
||||
};
|
||||
|
||||
// Start the timer and send the request
|
||||
this.xmlObject = obj;
|
||||
this.timer.start();
|
||||
obj.send((parameters && this.usePost) ? ps : null);
|
||||
return true;
|
||||
},
|
||||
|
||||
/** This method cancels the current operation if there is one.
|
||||
*/
|
||||
abort: function () {
|
||||
if (!this.isLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.doAbort();
|
||||
this.onAborted();
|
||||
},
|
||||
|
||||
|
||||
/** This method is used as a callback for the native loader object.
|
||||
*/
|
||||
loaderEvent: function () {
|
||||
if (!this.isLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
var obj = this.xmlObject;
|
||||
try {
|
||||
if (obj.readyState != 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj.status != 200) {
|
||||
this.doAbort();
|
||||
Base.Log.write('Base.XMLLoader.load(): server returned ' + obj.status);
|
||||
this.onServerError(obj.status);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
this.doAbort();
|
||||
Base.Log.write('Base.XMLLoader.load(): exception ' + (e.toString ? e.toString() : e) + ' while receiving');
|
||||
this.onNetworkError(e);
|
||||
return;
|
||||
}
|
||||
|
||||
var _r = obj.responseText;
|
||||
this.doAbort();
|
||||
this.onLoaded(_r);
|
||||
},
|
||||
|
||||
/** This method is responsible for deleting existing objects such as
|
||||
* the native loader and the timer component.
|
||||
*/
|
||||
doAbort: function () {
|
||||
this.isLoading = false;
|
||||
|
||||
if (this.xmlObject) {
|
||||
this.xmlObject.abort();
|
||||
delete this.xmlObject;
|
||||
this.xmlObject = null;
|
||||
}
|
||||
|
||||
if (this.timer) {
|
||||
this.timer.destroy();
|
||||
this.timer = null;
|
||||
}
|
||||
},
|
||||
|
||||
/** This method is called by the timer when the time imparted for loading the
|
||||
* data expires.
|
||||
*/
|
||||
timedOut: function () {
|
||||
if (!this.isLoading) {
|
||||
return;
|
||||
}
|
||||
Base.Log.write('Base.XMLLoader: timeout :(');
|
||||
this.doAbort();
|
||||
this.onTimeout();
|
||||
}
|
||||
|
||||
}, {
|
||||
|
||||
/** This class property stores the code to be used to generate native
|
||||
* loader objects. If it is empty, the code hasn't been determined yet,
|
||||
* and the "E" value indicates an error.
|
||||
*/
|
||||
objCode: "",
|
||||
|
||||
/** This class method generates native loader objects. If the objCode
|
||||
* class property has been initialised, it uses its content to generate
|
||||
* the new object. Otherwise it explores available options to try and
|
||||
* generate a native loader object.
|
||||
* @returns the native loader instance on success, null on failure
|
||||
*/
|
||||
makeNativeInstance: function () {
|
||||
var obj;
|
||||
|
||||
if (this.objCode == "E") {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.objCode != "") {
|
||||
eval('obj=' + this.objCode);
|
||||
} else {
|
||||
try {
|
||||
obj = new ActiveXObject("Msxml2.XMLHTTP");
|
||||
this.objCode = 'new ActiveXObject("Msxml2.XMLHTTP")';
|
||||
} catch (e) {
|
||||
try {
|
||||
obj = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
this.objCode = 'new ActiveXObject("Microsoft.XMLHTTP")';
|
||||
} catch (oc) {
|
||||
obj = null;
|
||||
}
|
||||
}
|
||||
if (!obj && typeof XMLHttpRequest != "undefined") {
|
||||
obj = new XMLHttpRequest();
|
||||
this.objCode = "new XMLHttpRequest()";
|
||||
}
|
||||
}
|
||||
|
||||
if (!obj && typeof obj == "object" && this.objCode != "E") {
|
||||
this.objCode = "E";
|
||||
obj = null;
|
||||
}
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
/** This class method encodes a hashtable containing request parameters into
|
||||
* a string usable when loading the data.
|
||||
* @param parameters the hashtable containing the parameters to be encoded.
|
||||
* @returns the encoded string
|
||||
*/
|
||||
encodeParameters: function (parameters) {
|
||||
var mk = new Array(), pl = parameters.keys();
|
||||
for (var i in pl) {
|
||||
var _k = pl[i], _pn = encodeURIComponent(_k), _v = parameters.get(_k);
|
||||
|
||||
if (_v instanceof Array) {
|
||||
for (var j in _v) {
|
||||
mk.push(_pn + '[]=' + encodeURIComponent(_v[j]));
|
||||
}
|
||||
} else {
|
||||
mk.push(_pn + '=' + encodeURIComponent(_v));
|
||||
}
|
||||
}
|
||||
|
||||
return mk.join('&');
|
||||
}
|
||||
|
||||
});
|
|
@ -1,85 +0,0 @@
|
|||
LWWidget = Base.inherits({
|
||||
|
||||
constructor: function () {
|
||||
this.base();
|
||||
LWWidget.main = this;
|
||||
if (LWWidget.debug) {
|
||||
Base.Log.initLog();
|
||||
}
|
||||
|
||||
this.loadPreferences();
|
||||
new LWWidget.Main();
|
||||
},
|
||||
|
||||
|
||||
loadPreferences: function () {
|
||||
var keys = ['lwLogin', 'lwPassword', 'lwRemAuth', 'lwGame', 'lwRemGame', 'lwColour'];
|
||||
var defs = ['', '', '0', '', '0', 'blue'];
|
||||
|
||||
this.preferences = new Base.Util.Hashtable();
|
||||
|
||||
if (window.widget) {
|
||||
// If we're really running inside Dashboard, load the preferences
|
||||
for (var i in keys) {
|
||||
var p = widget.preferenceForKey(keys[i]);
|
||||
if (p && p.length > 0) {
|
||||
this.preferences.put(keys[i], p);
|
||||
} else {
|
||||
this.preferences.put(keys[i], defs[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We're not inside Dashboard. Use defaults.
|
||||
for (var i in keys) {
|
||||
this.preferences.put(keys[i], defs[i]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
getPreference: function (key) {
|
||||
return (this.preferences.containsKey(key) ? this.preferences.get(key) : null);
|
||||
},
|
||||
|
||||
|
||||
setPreference: function (key, value) {
|
||||
if (this.preferences.containsKey(key) && typeof value == 'string') {
|
||||
Base.Log.write("Setting preference " + key + " to '" + value + "'");
|
||||
this.preferences.put(key, value);
|
||||
if (window.widget) {
|
||||
widget.setPreferenceForKey(key, value);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
showDebug: function () {
|
||||
if (!this.debugPanel) {
|
||||
this.debugPanel = new LWWidget.Debug();
|
||||
}
|
||||
this.debugPanel.show();
|
||||
}
|
||||
|
||||
|
||||
}, {
|
||||
|
||||
// Base URL for the LegacyWorlds website.
|
||||
base: 'http://www.legacyworlds.com',
|
||||
|
||||
// Enable/disable debugging
|
||||
debug: true,
|
||||
|
||||
// This widget's version number
|
||||
version: 1,
|
||||
|
||||
// Main widget instance
|
||||
main: null,
|
||||
|
||||
// Password storage
|
||||
password: '',
|
||||
|
||||
// When the widget page is loaded, initialise the component
|
||||
onLoad: function () {
|
||||
new LWWidget();
|
||||
}
|
||||
|
||||
}, "LWWidget");
|
|
@ -1,77 +0,0 @@
|
|||
LWWidget.Beta5 = LWWidget.Game.inherits({
|
||||
|
||||
constructor: function (path) {
|
||||
this.base(path);
|
||||
this.pageElement = 'b5Display';
|
||||
|
||||
this.pages[0] = new LWWidget.Beta5.Player(this);
|
||||
this.pages[1] = new LWWidget.Beta5.Planets(this);
|
||||
this.pages[2] = new LWWidget.Beta5.Fleets(this);
|
||||
this.pages[3] = new LWWidget.Beta5.Cash(this);
|
||||
this.pages[4] = new LWWidget.Beta5.Techs(this);
|
||||
this.pages[5] = new LWWidget.Beta5.Msg(this);
|
||||
this.pages[6] = new LWWidget.Beta5.Forums(this);
|
||||
this.pages[7] = new LWWidget.Beta5.Ticks(this);
|
||||
|
||||
this.setPage('player');
|
||||
|
||||
this.addSlot('updateServerTime');
|
||||
this.stUpdate = new Base.Timer(1000, true);
|
||||
this.stUpdate.bindEvent('Tick', 'updateServerTime', this);
|
||||
this.stUpdate.start();
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this.stUpdate.destroy();
|
||||
this.base();
|
||||
},
|
||||
|
||||
|
||||
setData: function (data) {
|
||||
this.base(data);
|
||||
this.serverTime = parseInt(data.getAttribute('serverTime'), 10);
|
||||
this.drawServerTime();
|
||||
},
|
||||
|
||||
|
||||
draw: function () {
|
||||
var _e = document.getElementById('gDisplay');
|
||||
if (!_e) {
|
||||
return;
|
||||
}
|
||||
|
||||
var _e2 = document.getElementById('b5Display');
|
||||
if (!_e2) {
|
||||
_e.style.overflow = 'visible';
|
||||
_e.innerHTML = '<table style="width:98%;height:208px;margin:0% 1%;padding:0%;border:0">'
|
||||
+ '<tr><td style="font-size:13px;color:white;height:16px;text-align:center" id="serverTime"> </td></tr>'
|
||||
+ '<tr><td style="font-size:13px;color:white"><div id="b5Display" style="overflow:auto;height:192px;width:100%"> </div></td></tr>'
|
||||
+ '</table>';
|
||||
}
|
||||
this.drawServerTime();
|
||||
|
||||
this.base();
|
||||
},
|
||||
|
||||
|
||||
updateServerTime: function () {
|
||||
if (!this.serverTime) {
|
||||
return;
|
||||
}
|
||||
this.serverTime ++;
|
||||
this.drawServerTime();
|
||||
},
|
||||
|
||||
drawServerTime: function (u) {
|
||||
var _e = document.getElementById('serverTime');
|
||||
if (!_e || !this.serverTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
_e.innerHTML = LWWidget.Game.formatTime(this.serverTime);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Register the version
|
||||
LWWidget.Game.versions().put('beta5', LWWidget.Beta5);
|
|
@ -1,17 +0,0 @@
|
|||
LWWidget.Beta5.Cash = LWWidget.Game.Page.inherits({
|
||||
|
||||
setData: function (data) {
|
||||
var _d = data.getChildren('Empire')[0].getChildren('Budget')[0];
|
||||
|
||||
this.income = parseInt(_d.getAttribute('income'), 10);
|
||||
this.upkeep = parseInt(_d.getAttribute('upkeep'), 10);
|
||||
this.profit = parseInt(_d.getAttribute('profit'), 10);
|
||||
},
|
||||
|
||||
draw: function (_e) {
|
||||
_e.innerHTML = '<p style="text-align:center"><br/><br/>Planetary income: <b>€' + Base.Util.formatNumber(this.income)
|
||||
+ '</b><br/><br/>Fleet upkeep: <b>€' + Base.Util.formatNumber(this.upkeep)
|
||||
+ '</b><br/><br/>Daily profit: <b>€' + Base.Util.formatNumber(this.profit) + '</p>';
|
||||
}
|
||||
|
||||
});
|
|
@ -1,55 +0,0 @@
|
|||
LWWidget.Beta5.Fleets = LWWidget.Game.Page.inherits({
|
||||
|
||||
setData: function (data) {
|
||||
var _d = data.getChildren('Empire')[0].getChildren('Fleets')[0];
|
||||
|
||||
this.fleets = parseInt(_d.getAttribute('count'), 10);
|
||||
if (this.fleets) {
|
||||
// Fleets in battle
|
||||
this.inBattle = parseInt(_d.getAttribute('inBattle'), 10);
|
||||
// Total fleet power
|
||||
this.power = parseInt(_d.getAttribute('power'), 10);
|
||||
// Ships types
|
||||
this.gaships = parseInt(_d.getAttribute('gaships'), 10);
|
||||
this.fighters = parseInt(_d.getAttribute('fighters'), 10);
|
||||
this.cruisers = parseInt(_d.getAttribute('cruisers'), 10);
|
||||
this.bcruisers = parseInt(_d.getAttribute('bcruisers'), 10);
|
||||
// Upkeep
|
||||
_d = data.getChildren('Empire')[0].getChildren('Budget')[0];
|
||||
this.upkeep = parseInt(_d.getAttribute('upkeep'), 10);
|
||||
}
|
||||
},
|
||||
|
||||
draw: function (_e) {
|
||||
if (this.fleets == 0) {
|
||||
_e.innerHTML = '<p style="text-align:center">No fleets</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
var _s = '<p style="text-align:center"><b>' + Base.Util.formatNumber(this.fleets)
|
||||
+ '</b> fleet' + (this.fleets > 1 ? 's' : '');
|
||||
if (this.inBattle) {
|
||||
_s += ' (<b>' + Base.Util.formatNumber(this.inBattle) + '</b> engaged in battle!)';
|
||||
}
|
||||
_s += '<br/><br/>Total fleet power: <b>' + Base.Util.formatNumber(this.power)
|
||||
+ '</b><br/>Upkeep: <b>€' + Base.Util.formatNumber(this.upkeep)
|
||||
+ '</b><br/><br/><u>Ship types</u><br/>';
|
||||
|
||||
if (this.gaships) {
|
||||
_s += 'G.A. ships: <b>' + Base.Util.formatNumber(this.gaships) + '</b><br/>';
|
||||
}
|
||||
if (this.fighters) {
|
||||
_s += 'Fighters: <b>' + Base.Util.formatNumber(this.fighters) + '</b><br/>';
|
||||
}
|
||||
if (this.cruisers) {
|
||||
_s += 'Cruisers: <b>' + Base.Util.formatNumber(this.cruisers) + '</b><br/>';
|
||||
}
|
||||
if (this.bcruisers) {
|
||||
_s += 'Battle Cruisers: <b>' + Base.Util.formatNumber(this.bcruisers) + '</b><br/>';
|
||||
}
|
||||
_s += '</p>';
|
||||
|
||||
_e.innerHTML = _s;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,125 +0,0 @@
|
|||
LWWidget.Beta5.Forums = LWWidget.Game.Page.inherits({
|
||||
|
||||
switchMode: function () {
|
||||
this.details = !this.details;
|
||||
this.game.draw();
|
||||
},
|
||||
|
||||
setData: function (data) {
|
||||
var _f = data.getChildren('Communications')[0].getChildren('Forums')[0];
|
||||
|
||||
// Read general forums
|
||||
var gf = _f.getChildren('GeneralForums'), gcats = new Base.Util.Hashtable();
|
||||
for (var i in gf) {
|
||||
var c = gf[i], desc = c.getChildren('Description')[0].getText(),
|
||||
cf = c.getChildren('Forum'), forums = new Array();
|
||||
for (var j in cf) {
|
||||
forums.push([cf[j].getText(), parseInt(cf[j].getAttribute('topics'), 10), parseInt(cf[j].getAttribute('unread'), 10)]);
|
||||
}
|
||||
gcats.put(desc, forums);
|
||||
}
|
||||
|
||||
// Read alliance forums
|
||||
var af = _f.getChildren('AllianceForums'), aForums = new Array();
|
||||
if (af.length) {
|
||||
af = af[0].getChildren('Forum');
|
||||
for (var i in af) {
|
||||
aForums.push([af[i].getText(), parseInt(af[i].getAttribute('topics'), 10), parseInt(af[i].getAttribute('unread'), 10)]);
|
||||
}
|
||||
}
|
||||
|
||||
// Store data
|
||||
this.general = gcats;
|
||||
this.alliance = aForums;
|
||||
},
|
||||
|
||||
|
||||
show: function () {
|
||||
this.details = false;
|
||||
},
|
||||
|
||||
draw: function (_e) {
|
||||
if (this.details) {
|
||||
_e.innerHTML = this.getDetailedHTML();
|
||||
} else {
|
||||
_e.innerHTML = this.getShortHTML();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
getShortHTML: function () {
|
||||
var text = new Array(), gk = this.general.keys();
|
||||
for (var i in gk) {
|
||||
text.push(this.catSummary(gk[i], this.general.get(gk[i])));
|
||||
}
|
||||
|
||||
if (this.alliance.length) {
|
||||
text.push(this.catSummary('Alliance forums', this.alliance));
|
||||
}
|
||||
|
||||
return '<p style="text-align:center">' + text.join('<br/>') + '<br/><br/><a href="#" onclick="Base.Comp.get('
|
||||
+ this._cid + ').switchMode();return false">Show details</a>';
|
||||
},
|
||||
|
||||
catSummary: function (name, list) {
|
||||
var s = '<u>' + name + '</u>: ';
|
||||
|
||||
var unread = this.countUnread(list);
|
||||
if (unread > 0) {
|
||||
s += '<b>' + Base.Util.formatNumber(unread) + '</b> unread topic' + (unread > 1 ? 's' : '');
|
||||
} else {
|
||||
s += 'no unread topics';
|
||||
}
|
||||
return s;
|
||||
},
|
||||
|
||||
countUnread: function (forums) {
|
||||
var s = 0;
|
||||
for (var i in forums) {
|
||||
s += forums[i][2];
|
||||
}
|
||||
return s;
|
||||
},
|
||||
|
||||
|
||||
getDetailedHTML: function () {
|
||||
var text = new Array(), gk = this.general.keys();
|
||||
|
||||
for (var i in gk) {
|
||||
text.push(this.catDetailed(gk[i], this.general.get(gk[i])));
|
||||
}
|
||||
|
||||
if (this.alliance.length) {
|
||||
text.push(this.catDetailed('Alliance forums', this.alliance));
|
||||
}
|
||||
|
||||
return '<p style="text-align:center"><a href="#" onclick="Base.Comp.get('
|
||||
+ this._cid + ').switchMode();return false">Hide details</a><br/><br/>' + text.join('<br/><br/>');
|
||||
},
|
||||
|
||||
catDetailed: function (name, forums) {
|
||||
if (!forums.length) {
|
||||
return "";
|
||||
}
|
||||
|
||||
var text = new Array();
|
||||
|
||||
text.push('<b>' + name + '</b>');
|
||||
for (var i in forums) {
|
||||
var f = forums[i], s = '<u>' + f[0] + '</u>: ';
|
||||
|
||||
if (f[1]) {
|
||||
s += '<b>' + Base.Util.formatNumber(f[1]) + '</b> topic' + (f[1] > 1 ? 's' : '');
|
||||
if (f[2]) {
|
||||
s += ' (<b>' + Base.Util.formatNumber(f[2]) + '</b> unread)';
|
||||
}
|
||||
} else {
|
||||
s += 'empty forum';
|
||||
}
|
||||
text.push(s);
|
||||
}
|
||||
|
||||
return text.join('<br/>');
|
||||
}
|
||||
|
||||
});
|
|
@ -1,71 +0,0 @@
|
|||
LWWidget.Beta5.Msg = LWWidget.Game.Page.inherits({
|
||||
|
||||
setData: function (data) {
|
||||
var _d = data.getChildren('Communications')[0].getChildren('Messages')[0];
|
||||
|
||||
// Get default folders
|
||||
var _f = _d.getChildren('DefaultFolder');
|
||||
for (var i in _f) {
|
||||
var _a = [parseInt(_f[i].getAttribute('all'), 10), parseInt(_f[i].getAttribute('new'), 10)];
|
||||
switch (_f[i].getAttribute('id')) {
|
||||
case 'IN': this.inbox = _a; break;
|
||||
case 'INT': this.internal = _a; break;
|
||||
case 'OUT': this.outbox = _a; break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get custom folders
|
||||
this.custom = new Base.Util.Hashtable();
|
||||
_f = _d.getChildren('CustomFolder');
|
||||
for (var i in _f) {
|
||||
this.custom.put(_f[i].getAttribute('id'), [parseInt(_f[i].getAttribute('all'), 10), parseInt(_f[i].getAttribute('new'), 10), _f[i].getText()]);
|
||||
}
|
||||
},
|
||||
|
||||
show: function () {
|
||||
this.dCustom = false;
|
||||
},
|
||||
|
||||
draw: function (_e) {
|
||||
var _s = '<p style="text-align:center">';
|
||||
_s += this.folderCode('Inbox', this.inbox[0], this.inbox[1]) + '<br/>';
|
||||
_s += this.folderCode('Transmissions', this.internal[0], this.internal[1]) + '<br/>'
|
||||
_s += this.folderCode('Sent messages', this.outbox[0], this.outbox[1]) + '<br/><br/>';
|
||||
|
||||
if (this.custom.isEmpty()) {
|
||||
_s += 'No custom folders';
|
||||
} else if (this.dCustom) {
|
||||
_s += '<a href="#" onclick="Base.Comp.get(' + this._cid + ').switchCustom();return false">Hide custom folders</a><br/>';
|
||||
var cf = this.custom.values();
|
||||
for (var i in cf) {
|
||||
_s += this.folderCode(cf[i][2], cf[i][0], cf[i][1]) + '<br/>';
|
||||
}
|
||||
} else {
|
||||
_s += '<a href="#" onclick="Base.Comp.get(' + this._cid + ').switchCustom();return false">Display custom folders</a>';
|
||||
}
|
||||
|
||||
_s += '</p>';
|
||||
_e.innerHTML = _s;
|
||||
},
|
||||
|
||||
folderCode: function (name, a, n) {
|
||||
var _s = '<b>' + name + '</b>: ';
|
||||
if (a) {
|
||||
if (n) {
|
||||
_s += '<b>' + Base.Util.formatNumber(n) + '</b> new message' + (n > 1 ? 's' : '');
|
||||
} else {
|
||||
_s += 'no new messages';
|
||||
}
|
||||
_s += ' (<b>' + Base.Util.formatNumber(a) + '</b> total)';
|
||||
} else {
|
||||
_s += 'no messages';
|
||||
}
|
||||
return _s;
|
||||
},
|
||||
|
||||
switchCustom: function () {
|
||||
this.dCustom = !this.dCustom;
|
||||
this.game.draw();
|
||||
}
|
||||
|
||||
});
|
|
@ -1,86 +0,0 @@
|
|||
LWWidget.Beta5.Planets = LWWidget.Game.Page.inherits({
|
||||
|
||||
setData: function (data) {
|
||||
var _d = data.getChildren('Empire')[0].getChildren('Planets')[0];
|
||||
|
||||
this.planets = parseInt(_d.getAttribute('count'), 10);
|
||||
this.pList = new Array();
|
||||
if (this.planets) {
|
||||
// Planets under attack
|
||||
this.underAttack = parseInt(_d.getAttribute('siege'), 10);
|
||||
// Happiness / Corruption
|
||||
this.avgHappiness = parseInt(_d.getAttribute('avgHap'), 10);
|
||||
this.avgCorruption = parseInt(_d.getAttribute('avgCor'), 10);
|
||||
// Population
|
||||
this.totPopulation = parseInt(_d.getAttribute('totPop'), 10);
|
||||
this.avgPopulation = parseInt(_d.getAttribute('avgPop'), 10);
|
||||
// Factories
|
||||
this.totFactories = parseInt(_d.getAttribute('totFac'), 10);
|
||||
this.avgFactories = parseInt(_d.getAttribute('avgFac'), 10);
|
||||
// Factories
|
||||
this.totTurrets = parseInt(_d.getAttribute('totTur'), 10);
|
||||
this.avgTurrets = parseInt(_d.getAttribute('avgTur'), 10);
|
||||
|
||||
// Planet list
|
||||
var _l = _d.getChildren('List')[0].getChildren('Planet');
|
||||
for (var i in _l) {
|
||||
this.pList.push(_l[i].getText());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
show: function () {
|
||||
this.mode = 0;
|
||||
},
|
||||
|
||||
draw: function (_e) {
|
||||
_e.innerHTML = (this.mode == 0 || !this.planets) ? this.getStats() : this.getList();
|
||||
},
|
||||
|
||||
setMode: function (m) {
|
||||
this.mode = m;
|
||||
if (this.game) {
|
||||
this.game.draw();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
getStats: function () {
|
||||
if (this.planets == 0) {
|
||||
return '<p style="text-align:center">No planets.</p>';
|
||||
}
|
||||
|
||||
var _s = '<p style="text-align:center"><b>' + Base.Util.formatNumber(this.planets) + '</b> planet'
|
||||
+ (this.planets > 1 ? 's' : '') + '<br/>';
|
||||
if (this.underAttack) {
|
||||
_s += '<b>' + Base.Util.formatNumber(this.underAttack) + ' planet'
|
||||
+ (this.underAttack > 1 ? 's' : '') + ' under attack!</b>';
|
||||
} else {
|
||||
_s += 'No planets under attack';
|
||||
}
|
||||
|
||||
_s += '<br/><br/>Average happiness: <b>' + this.avgHappiness + '%</b><br/>Average corruption: <b>'
|
||||
+ this.avgCorruption + '%</b><br/>Population: <b>' + Base.Util.formatNumber(this.totPopulation) + '</b>';
|
||||
if (this.planets > 1) {
|
||||
_s += ' (<b>' + Base.Util.formatNumber(this.avgPopulation) + '</b> on average)';
|
||||
}
|
||||
_s += '<br/>Factories: <b>' + Base.Util.formatNumber(this.totFactories) + '</b>';
|
||||
if (this.planets > 1) {
|
||||
_s += ' (<b>' + Base.Util.formatNumber(this.avgFactories) + '</b> on average)';
|
||||
}
|
||||
_s += '<br/>Turrets: <b>' + Base.Util.formatNumber(this.totTurrets) + '</b>';
|
||||
if (this.planets > 1) {
|
||||
_s += ' (<b>' + Base.Util.formatNumber(this.avgTurrets) + '</b> on average)';
|
||||
}
|
||||
_s += '<br/><br/><a href="#" onclick="Base.Comp.get(' + this._cid + ').setMode(1);return false">View list</a></p>';
|
||||
|
||||
return _s;
|
||||
},
|
||||
|
||||
getList: function () {
|
||||
return '<p style="text-align:center"><a href="#" onclick="Base.Comp.get(' + this._cid
|
||||
+ ').setMode(0);return false"><<- Back</a><br/><br/><b>'
|
||||
+ this.pList.join('</b><br/><b>') + '</b></p>';
|
||||
}
|
||||
|
||||
});
|
|
@ -1,82 +0,0 @@
|
|||
LWWidget.Beta5.Player = LWWidget.Game.Page.inherits({
|
||||
|
||||
setData: function (data) {
|
||||
var _d = data.getChildren('Player')[0];
|
||||
|
||||
// Player name and cash
|
||||
this.playerName = _d.getAttribute('name');
|
||||
this.cash = _d.getAttribute('cash');
|
||||
|
||||
// Alliance status
|
||||
var _a = _d.getChildren('Alliance');
|
||||
if (_a.length) {
|
||||
_a = _a[0];
|
||||
this.alliance = { joined: (_a.getAttribute('inalliance') == '1'), tag: _a.getAttribute('tag') };
|
||||
} else {
|
||||
this.alliance = null;
|
||||
}
|
||||
|
||||
// General rankings
|
||||
_a = _d.getChildren('Rankings')[0];
|
||||
var _r = _a.getChildren('Ranking');
|
||||
for (var i in _r) {
|
||||
if (_r[i].getText() != 'General Ranking') {
|
||||
continue;
|
||||
}
|
||||
this.points = _r[i].getAttribute('points');
|
||||
this.rank = _r[i].getAttribute('rank');
|
||||
break;
|
||||
}
|
||||
|
||||
// Planets / planets under attack
|
||||
_d = data.getChildren('Empire')[0].getChildren('Planets')[0];
|
||||
this.planets = parseInt(_d.getAttribute('count'), 10);
|
||||
this.underAttack = parseInt(_d.getAttribute('siege'), 10);
|
||||
|
||||
// Fleets / fleets in battle
|
||||
_d = data.getChildren('Empire')[0].getChildren('Fleets')[0];
|
||||
this.fleets = parseInt(_d.getAttribute('count'), 10);
|
||||
this.inBattle = parseInt(_d.getAttribute('inBattle'), 10);
|
||||
},
|
||||
|
||||
draw: function (_e) {
|
||||
if (!this.playerName) {
|
||||
return;
|
||||
}
|
||||
|
||||
var str = '<p style="text-align:center">Player <b>' + this.playerName + '</b>';
|
||||
if (this.alliance && this.alliance.joined) {
|
||||
str += ' [<b>' + this.alliance.tag + '</b>]';
|
||||
} else if (this.alliance && !this.alliance.joined) {
|
||||
str += '<br/>Requesting to join alliance [<b>' + this.alliance.tag + '</b>]';
|
||||
}
|
||||
|
||||
str += '<br/><br/>Cash: <b>€' + Base.Util.formatNumber(this.cash) + '</b>'
|
||||
+ '<br/>General ranking: <b>#' + Base.Util.formatNumber(this.rank) + '</b> (<b>'
|
||||
+ Base.Util.formatNumber(this.points) + '</b> points)<br/><br/>';
|
||||
|
||||
if (this.planets == 0) {
|
||||
str += "No planets";
|
||||
} else {
|
||||
str += '<b>' + Base.Util.formatNumber(this.planets) + '</b> planet' + (this.planets > 1 ? 's' : '');
|
||||
if (this.underAttack > 0) {
|
||||
str += ' (<b>' + Base.Util.formatNumber(this.underAttack) + '</b> under attack!)';
|
||||
}
|
||||
}
|
||||
str += '<br/>';
|
||||
|
||||
if (this.fleets == 0) {
|
||||
str += "No fleets";
|
||||
} else {
|
||||
str += '<b>' + Base.Util.formatNumber(this.fleets) + '</b> fleet' + (this.fleets > 1 ? 's' : '');
|
||||
if (this.inBattle > 0) {
|
||||
str += ' (<b>' + Base.Util.formatNumber(this.inBattle) + '</b> in battle)';
|
||||
}
|
||||
}
|
||||
|
||||
str += '</p>';
|
||||
|
||||
_e.innerHTML = str;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,37 +0,0 @@
|
|||
LWWidget.Beta5.Techs = LWWidget.Game.Page.inherits({
|
||||
|
||||
setData: function (data) {
|
||||
var _d = data.getChildren('Empire')[0].getChildren('Research')[0];
|
||||
|
||||
this.points = parseInt(_d.getAttribute('points'), 10);
|
||||
this.newTechs = parseInt(_d.getAttribute('new'), 10);
|
||||
this.foreseen = parseInt(_d.getAttribute('foreseen'), 10);
|
||||
|
||||
_d = _d.getChildren('RBudget')[0];
|
||||
this.fundamental = parseInt(_d.getAttribute('fundamental'), 10);
|
||||
this.military = parseInt(_d.getAttribute('military'), 10);
|
||||
this.civilian = parseInt(_d.getAttribute('civilian'), 10);
|
||||
},
|
||||
|
||||
draw: function (_e) {
|
||||
var _s = '<p style="text-align:center">';
|
||||
if (this.newTechs == 0) {
|
||||
_s += 'No new technologies discovered.';
|
||||
} else {
|
||||
_s += '<b>' + this.newTechs + '</b> new technolog' + (this.newTechs > 1 ? 'ies' : 'y') + ' discovered.';
|
||||
}
|
||||
_s += '<br/>';
|
||||
if (this.foreseen == 0) {
|
||||
_s += 'No breakthroughs foreseen.';
|
||||
} else {
|
||||
_s += '<b>' + this.foreseen + '</b> breakthrough' + (this.foreseen > 1 ? 's' : '') + ' foreseen.';
|
||||
}
|
||||
_s += '<br/><br/><u>Research budget</u><br/><br/><b>' + Base.Util.formatNumber(this.points) + '</b> research points per day<br/><b>'
|
||||
+ this.fundamental + '%</b> allocated to Fundamental research<br/><b>'
|
||||
+ this.military + '%</b> allocated to Military research<br/><b>'
|
||||
+ this.civilian + '%</b> allocated to Civilian research</p>';
|
||||
|
||||
_e.innerHTML = _s;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,121 +0,0 @@
|
|||
LWWidget.Beta5.Ticks = LWWidget.Game.Page.inherits({
|
||||
|
||||
constructor: function (game) {
|
||||
this.base(game);
|
||||
|
||||
this.addSlot('update');
|
||||
this.timer = new Base.Timer(1000, true);
|
||||
this.timer.bindEvent('Tick', 'update', this);
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this.timer.destroy();
|
||||
this.base();
|
||||
},
|
||||
|
||||
|
||||
setData: function (data) {
|
||||
var tList = data.getChildren('Ticks')[0].getChildren('Tick'), ticks = new Array();
|
||||
|
||||
for (var i in tList) {
|
||||
var tick = new Array();
|
||||
tick[0] = tList[i].getText();
|
||||
tick[1] = parseInt(tList[i].getAttribute('first'), 10);
|
||||
tick[2] = parseInt(tList[i].getAttribute('interval'), 10);
|
||||
|
||||
var l = tList[i].getAttribute('last');
|
||||
if (typeof l == 'string') {
|
||||
tick[3] = parseInt(l, 10);
|
||||
} else {
|
||||
tick[3] = null;
|
||||
}
|
||||
|
||||
ticks.push(tick);
|
||||
}
|
||||
|
||||
this.tDiff = (new Date()).getTime() - (parseInt(data.getAttribute('serverTime'), 10) * 1000);
|
||||
this.ticks = ticks;
|
||||
},
|
||||
|
||||
|
||||
show: function () {
|
||||
this.timer.start();
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.timer.stop();
|
||||
},
|
||||
|
||||
|
||||
draw: function (_e) {
|
||||
var text = new Array();
|
||||
|
||||
for (var i in this.ticks) {
|
||||
text.push('Next ' + this.ticks[i][0] + ': <span id="dtick' + i + '"> </span>');
|
||||
}
|
||||
|
||||
_e.innerHTML = '<p style="text-align:center">' + text.join('<br/>') + '</p>';
|
||||
this.update();
|
||||
},
|
||||
|
||||
|
||||
update: function () {
|
||||
this.computeNextTicks();
|
||||
|
||||
for (var i in this.ticks) {
|
||||
var t;
|
||||
|
||||
if (typeof this.ticks[i][5] == 'number') {
|
||||
var d, h, m, s;
|
||||
|
||||
h = this.ticks[i][5] % 86400; d = (this.ticks[i][5] - h) / 86400;
|
||||
m = h % 3600; h = (h - m) / 3600;
|
||||
s = m % 60; m = (m - s) / 60;
|
||||
|
||||
if (h < 10) { h = '0' + h; }
|
||||
if (m < 10) { m = '0' + m; }
|
||||
if (s < 10) { s = '0' + s; }
|
||||
|
||||
t = '<b>' + h + ':' + m + ':' + s + '</b>';
|
||||
if (d > 0) {
|
||||
t = '<b>' + d + '</b> day' + (d > 1 ? 's' : '') + ', ' + t;
|
||||
}
|
||||
} else {
|
||||
t = 'never';
|
||||
}
|
||||
|
||||
var e = document.getElementById('dtick' + i);
|
||||
if (!e) {
|
||||
break;
|
||||
}
|
||||
e.innerHTML = t;
|
||||
}
|
||||
},
|
||||
|
||||
computeNextTicks: function () {
|
||||
var now = Math.round(((new Date()).getTime() - this.tDiff) / 1000);
|
||||
for (var i in this.ticks) {
|
||||
if (this.ticks[i][3] && now > this.ticks[i][3]) {
|
||||
this.ticks[i][4] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (now <= this.ticks[i][1]) {
|
||||
this.ticks[i][4] = this.ticks[i][1];
|
||||
continue;
|
||||
}
|
||||
|
||||
var d = now - this.ticks[i][1], m = (d - (d % this.ticks[i][2])) / this.ticks[i][2];
|
||||
this.ticks[i][4] = this.ticks[i][1] + (m + 1) * this.ticks[i][2];
|
||||
}
|
||||
|
||||
for (var i in this.ticks) {
|
||||
if (typeof this.ticks[i][4] != 'number') {
|
||||
this.ticks[i][5] = null;
|
||||
} else {
|
||||
this.ticks[i][5] = this.ticks[i][4] - now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
|
@ -1,25 +0,0 @@
|
|||
LWWidget.Data = Base.inherits({
|
||||
|
||||
constructor: function (name) {
|
||||
this.base();
|
||||
this.name = name;
|
||||
this.attributes = new Base.Util.Hashtable();
|
||||
},
|
||||
|
||||
setAttribute: function (name, value) {
|
||||
this.attributes.put(name, value);
|
||||
},
|
||||
|
||||
getAttribute: function (name) {
|
||||
return (this.attributes.containsKey(name) ? this.attributes.get(name) : null);
|
||||
},
|
||||
|
||||
getChildren: function (name) {
|
||||
return new Array();
|
||||
},
|
||||
|
||||
getText: function () {
|
||||
return "";
|
||||
}
|
||||
|
||||
});
|
|
@ -1,12 +0,0 @@
|
|||
LWWidget.Data.Leaf = LWWidget.Data.inherits({
|
||||
|
||||
constructor: function (name, text) {
|
||||
this.base(name);
|
||||
this.text = text;
|
||||
},
|
||||
|
||||
getText: function () {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,130 +0,0 @@
|
|||
LWWidget.Data.Loader = Base.Comp.inherits({
|
||||
|
||||
constructor: function (login, password) {
|
||||
this.base();
|
||||
|
||||
this.addEvent('CommError');
|
||||
this.addEvent('FatalError');
|
||||
this.addEvent('Kick');
|
||||
this.addEvent('Load');
|
||||
this.addEvent('LoginFailure');
|
||||
this.addEvent('Maintenance');
|
||||
|
||||
this.addSlot('loaderDestroyed');
|
||||
this.addSlot('dataReceived');
|
||||
|
||||
this.loader = new Base.XMLLoader('', true);
|
||||
this.loader.bindEvent('Destroy', 'loaderDestroyed', this);
|
||||
this.loader.bindEvent('NetworkError', 'onCommError', this);
|
||||
this.loader.bindEvent('ServerError', 'onCommError', this);
|
||||
this.loader.bindEvent('Timeout', 'onCommError', this);
|
||||
this.loader.bindEvent('Unsupported', 'onCommError', this);
|
||||
this.loader.bindEvent('Aborted', 'onCommError', this);
|
||||
this.loader.bindEvent('Loaded', 'dataReceived', this);
|
||||
|
||||
this.params = new Base.Util.Hashtable();
|
||||
this.params.put('__s', '1');
|
||||
this.params.put('__l', login);
|
||||
this.params.put('__p', password);
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
if (this.loader) {
|
||||
this.loader.destroy();
|
||||
}
|
||||
this.base();
|
||||
},
|
||||
|
||||
|
||||
load: function (from) {
|
||||
if (this.loader.isLoading) {
|
||||
return false;
|
||||
}
|
||||
this.loader.changeParameters(LWWidget.base + '/index.php/' + from + '.xml');
|
||||
this.loader.load(this.params);
|
||||
},
|
||||
|
||||
|
||||
loaderDestroyed: function () {
|
||||
this.loader = null;
|
||||
},
|
||||
|
||||
|
||||
dataReceived: function (data) {
|
||||
var _xml = Base.Util.parseXML(data);
|
||||
if (!_xml) {
|
||||
this.onCommError();
|
||||
return;
|
||||
}
|
||||
|
||||
var _doc = _xml.documentElement;
|
||||
if (_doc.nodeName == 'Maintenance') {
|
||||
var _r, _u, _c;
|
||||
_r = LWWidget.Data.Loader.getXMLText(_doc, 'Reason');
|
||||
_u = LWWidget.Data.Loader.getXMLText(_doc, 'Until');
|
||||
_c = LWWidget.Data.Loader.getXMLText(_doc, 'Current');
|
||||
this.onMaintenance(_r, _u, _c);
|
||||
} else if (_doc.nodeName == 'FatalError') {
|
||||
this.onFatalError(_doc.getAttribute('code'), LWWidget.Data.Loader.getXMLText(_doc, 'Text'));
|
||||
} else if (_doc.nodeName == 'Kicked') {
|
||||
this.onKick(LWWidget.Data.Loader.getXMLText(_doc, 'Reason'));
|
||||
} else if (_doc.nodeName == 'Failed') {
|
||||
this.onLoginFailure(_doc.getAttribute('code'));
|
||||
} else {
|
||||
var _data = LWWidget.Data.Loader.parse(_doc);
|
||||
if (_data) {
|
||||
this.onLoad(_data);
|
||||
} else {
|
||||
this.onCommError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, {
|
||||
|
||||
getXMLText: function (node, name) {
|
||||
var _t = '';
|
||||
for (var i=0;i<node.childNodes.length;i++) {
|
||||
var _c = node.childNodes[i];
|
||||
if (_c.nodeType == 1 && _c.nodeName == name) {
|
||||
_t += _c.childNodes[0].nodeValue;
|
||||
}
|
||||
}
|
||||
return _t;
|
||||
},
|
||||
|
||||
parse: function (xmlNode) {
|
||||
if (xmlNode.nodeType != 1 || xmlNode.nodeName != 'Node') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var _in = (xmlNode.getAttribute('node') == '1'), _n;
|
||||
if (_in) {
|
||||
_n = new LWWidget.Data.Node(xmlNode.getAttribute('name'));
|
||||
} else {
|
||||
_n = new LWWidget.Data.Leaf(xmlNode.getAttribute('name'), LWWidget.Data.Loader.getXMLText(xmlNode, 'Text'));
|
||||
}
|
||||
|
||||
for (var i=0;i<xmlNode.childNodes.length;i++) {
|
||||
var _c = xmlNode.childNodes[i];
|
||||
if (_c.nodeType != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_c.nodeName == 'Attr') {
|
||||
var _t;
|
||||
if (_c.childNodes.length) {
|
||||
_t = _c.childNodes[0].nodeValue;
|
||||
} else {
|
||||
_t = '';
|
||||
}
|
||||
_n.setAttribute(_c.getAttribute('name'), _t);
|
||||
} else if (_c.nodeName == 'Node' && _in) {
|
||||
_n.addChild(this.parse(_c));
|
||||
}
|
||||
}
|
||||
|
||||
return _n;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,25 +0,0 @@
|
|||
LWWidget.Data.Node = LWWidget.Data.inherits({
|
||||
|
||||
constructor: function (name) {
|
||||
this.base(name);
|
||||
this.contents = new Array();
|
||||
},
|
||||
|
||||
addChild: function (child) {
|
||||
if (child instanceof LWWidget.Data.Node || child instanceof LWWidget.Data.Leaf) {
|
||||
this.contents.push(child);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
getChildren: function (name) {
|
||||
var _c = new Array();
|
||||
for (var i in this.contents) {
|
||||
if (this.contents[i] && this.contents[i].name == name) {
|
||||
_c.push(this.contents[i]);
|
||||
}
|
||||
}
|
||||
return _c;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,67 +0,0 @@
|
|||
LWWidget.Debug = Base.Comp.inherits({
|
||||
|
||||
constructor: function () {
|
||||
this.base();
|
||||
this.addSlot('drawLog');
|
||||
|
||||
this.timer = new Base.Timer(1000, true);
|
||||
this.timer.bindEvent('Tick', 'drawLog', this);
|
||||
},
|
||||
|
||||
show: function () {
|
||||
document.getElementById('debugLink').style.display = 'none';
|
||||
document.getElementById('mainDiv').style.display = 'none';
|
||||
this.lastLength = -1;
|
||||
this.draw();
|
||||
document.getElementById('debugDiv').style.display = 'block';
|
||||
this.timer.start();
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.timer.stop();
|
||||
document.getElementById('debugDiv').style.display = 'none';
|
||||
document.getElementById('debugLink').style.display = 'block';
|
||||
document.getElementById('mainDiv').style.display = 'block';
|
||||
},
|
||||
|
||||
draw: function () {
|
||||
var _str = '<table id="debugTable"><tr id="dbgHdr"><td><b>Debug mode</b></td>'
|
||||
+ '<td style="text-align:right"><a href="#" onclick="Base.Comp.get('
|
||||
+ this._cid + ').clear()">Flush log</a> - <a href="#" onclick="Base.Comp.get('
|
||||
+ this._cid + ').hide()">Hide</a></td></tr>'
|
||||
+ '<tr><td colspan="2"><div style="overflow:auto;height:260px;width:296px;color:white" id="dbgContents"> </div></td></tr></table>';
|
||||
document.getElementById('debugDiv').innerHTML = _str;
|
||||
this.drawLog();
|
||||
},
|
||||
|
||||
clear: function () {
|
||||
Base.Log.flush();
|
||||
this.drawLog();
|
||||
},
|
||||
|
||||
drawLog: function () {
|
||||
var _e = document.getElementById('dbgContents');
|
||||
if (!_e) {
|
||||
return;
|
||||
}
|
||||
|
||||
var _l = Base.Log.get();
|
||||
if (_l.length == this.lastLength) {
|
||||
return;
|
||||
}
|
||||
this.lastLength = _l.length;
|
||||
|
||||
var _s;
|
||||
if (_l.length == 0) {
|
||||
_s = '<p style="text-align:center">The log is empty</p>';
|
||||
} else {
|
||||
_s = '<p>';
|
||||
for (var i=_l.length;i>0;i--) {
|
||||
_s += '[' + i + '] ' + _l[i-1] + '<br/>';
|
||||
}
|
||||
_s += '</p>';
|
||||
}
|
||||
_e.innerHTML = _s;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,168 +0,0 @@
|
|||
LWWidget.Game = Base.Comp.inherits({
|
||||
|
||||
constructor: function (path) {
|
||||
this.base();
|
||||
this.path = path;
|
||||
|
||||
this.addEvent('RequestUpdate');
|
||||
this.addSlot('startDataUpdate');
|
||||
|
||||
this.pageElement = 'gDisplay';
|
||||
|
||||
this.autoUpdate = new Base.Timer(30000, true);
|
||||
this.autoUpdate.bindEvent('Tick', 'startDataUpdate', this);
|
||||
this.autoUpdate.start();
|
||||
|
||||
this.pages = [null, null, null, null, null, null, null, null];
|
||||
this.page = null;
|
||||
this.data = null;
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this.autoUpdate.destroy();
|
||||
if (this.page) {
|
||||
this.page.hide();
|
||||
this.page = null;
|
||||
}
|
||||
for (var i in this.pages) {
|
||||
if (this.pages[i]) {
|
||||
var _p = this.pages[i];
|
||||
this.pages[i] = null;
|
||||
_p.destroy();
|
||||
}
|
||||
}
|
||||
this.base();
|
||||
},
|
||||
|
||||
|
||||
startDataUpdate: function () {
|
||||
this.onRequestUpdate(this.path);
|
||||
},
|
||||
|
||||
setData: function (data) {
|
||||
this.data = data;
|
||||
for (var i in this.pages) {
|
||||
if (this.pages[i]) {
|
||||
this.pages[i].setData(data);
|
||||
}
|
||||
}
|
||||
this.draw();
|
||||
},
|
||||
|
||||
|
||||
setPage: function (pName) {
|
||||
// Check for a valid page name
|
||||
if (!LWWidget.Game.pageMap().containsKey(pName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if something was changed
|
||||
var _p = this.pages[LWWidget.Game.pageMap().get(pName)];
|
||||
if (_p && this.page && _p._cid == this.page._cid || !(_p || this.page)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide current page and show new page
|
||||
if (this.page) {
|
||||
this.page.hide();
|
||||
}
|
||||
this.page = _p;
|
||||
if (_p) {
|
||||
this.page.show();
|
||||
}
|
||||
this.draw();
|
||||
},
|
||||
|
||||
draw: function () {
|
||||
var _e = document.getElementById(this.pageElement);
|
||||
if (_e) {
|
||||
if (this.page) {
|
||||
this.page.draw(_e);
|
||||
} else {
|
||||
_e.innerHTML = '<p style="text-align:center">Page not implemented</p>';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
show: function () {
|
||||
this.startDataUpdate();
|
||||
this.autoUpdate.start();
|
||||
if (this.page) {
|
||||
this.page.show();
|
||||
}
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.autoUpdate.stop();
|
||||
if (this.page) {
|
||||
this.page.hide();
|
||||
}
|
||||
}
|
||||
|
||||
}, {
|
||||
|
||||
pageMapInst: null,
|
||||
|
||||
versionsInst: null,
|
||||
|
||||
pageMap: function () {
|
||||
if (!LWWidget.Game.pageMapInst) {
|
||||
var _h = new Base.Util.Hashtable();
|
||||
_h.put('player', 0);
|
||||
_h.put('planets', 1);
|
||||
_h.put('fleets', 2);
|
||||
_h.put('budget', 3);
|
||||
_h.put('tech', 4);
|
||||
_h.put('msg', 5);
|
||||
_h.put('forums', 6);
|
||||
_h.put('ticks', 7);
|
||||
LWWidget.Game.pageMapInst = _h;
|
||||
}
|
||||
return LWWidget.Game.pageMapInst;
|
||||
},
|
||||
|
||||
versions: function () {
|
||||
if (!LWWidget.Game.versionsInst) {
|
||||
LWWidget.Game.versionsInst = new Base.Util.Hashtable();
|
||||
}
|
||||
return LWWidget.Game.versionsInst;
|
||||
},
|
||||
|
||||
formatTime: function (ts) {
|
||||
var d = new Date(ts * 1000);
|
||||
var str, s2;
|
||||
|
||||
s2 = d.getUTCHours().toString();
|
||||
if (s2.length == 1) {
|
||||
s2 = "0" + s2;
|
||||
}
|
||||
str = s2 + ':';
|
||||
|
||||
s2 = d.getUTCMinutes().toString();
|
||||
if (s2.length == 1) {
|
||||
s2 = "0" + s2;
|
||||
}
|
||||
str += s2 + ':';
|
||||
|
||||
s2 = d.getUTCSeconds().toString();
|
||||
if (s2.length == 1) {
|
||||
s2 = "0" + s2;
|
||||
}
|
||||
str += s2 + ' on ';
|
||||
|
||||
s2 = d.getUTCDate().toString();
|
||||
if (s2.length == 1) {
|
||||
s2 = "0" + s2;
|
||||
}
|
||||
str += s2 + '/';
|
||||
|
||||
s2 = (d.getUTCMonth() + 1).toString();
|
||||
if (s2.length == 1) {
|
||||
s2 = "0" + s2;
|
||||
}
|
||||
str += s2 + '/' + d.getUTCFullYear();
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,34 +0,0 @@
|
|||
LWWidget.Game.Page = Base.Comp.inherits({
|
||||
|
||||
constructor: function (game) {
|
||||
this.base();
|
||||
|
||||
this.addSlot('gameDestroyed');
|
||||
this.game = game;
|
||||
this.game.bindEvent('Destroy', 'gameDestroyed', this);
|
||||
},
|
||||
|
||||
writeContents: function (contents) {
|
||||
var e = document.getElementById('gDisplay');
|
||||
if (e) {
|
||||
e.innerHTML = contents;
|
||||
}
|
||||
},
|
||||
|
||||
gameDestroyed: function () {
|
||||
this.game = null;
|
||||
},
|
||||
|
||||
setData: function (data) {
|
||||
},
|
||||
|
||||
draw: function (_e) {
|
||||
},
|
||||
|
||||
show: function () {
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
}
|
||||
|
||||
});
|
|
@ -1,73 +0,0 @@
|
|||
LWWidget.GameDisplay = LWWidget.Page.inherits({
|
||||
|
||||
constructor: function () {
|
||||
this.base();
|
||||
|
||||
this.addSlot('gameDestroyed');
|
||||
this.addEvent('Refresh');
|
||||
|
||||
this.gPath = '';
|
||||
this.game = null;
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
if (this.game) {
|
||||
this.game.destroy();
|
||||
}
|
||||
this.base();
|
||||
},
|
||||
|
||||
|
||||
setGame: function (gClass, gPath) {
|
||||
if (this.game) {
|
||||
this.game.destroy();
|
||||
}
|
||||
this.game = new gClass(gPath);
|
||||
this.game.bindEvent('Destroy', 'gameDestroyed', this);
|
||||
this.game.bindEvent('RequestUpdate', 'onRefresh', this);
|
||||
},
|
||||
|
||||
gameDestroyed: function () {
|
||||
this.game = null;
|
||||
},
|
||||
|
||||
|
||||
handleData: function (data) {
|
||||
if (this.game) {
|
||||
this.game.setData(data);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
hide: function () {
|
||||
if (this.game) {
|
||||
this.game.hide();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
show: function () {
|
||||
if (this.game) {
|
||||
this.game.show();
|
||||
}
|
||||
this.draw();
|
||||
},
|
||||
|
||||
|
||||
setPage: function (pName) {
|
||||
if (this.game) {
|
||||
this.game.setPage(pName);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
draw: function () {
|
||||
if (!document.getElementById('gDisplay')) {
|
||||
this.writeContents('<div id="gDisplay" style="overflow:auto;width:100%;height:100%"> </div>');
|
||||
}
|
||||
if (this.game) {
|
||||
this.game.draw();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
|
@ -1,65 +0,0 @@
|
|||
LWWidget.GameSelector = LWWidget.Page.inherits({
|
||||
|
||||
constructor: function () {
|
||||
this.base();
|
||||
this.games = [];
|
||||
|
||||
this.addEvent('Select');
|
||||
},
|
||||
|
||||
|
||||
setGames: function (games) {
|
||||
if (games instanceof Array) {
|
||||
this.games = games;
|
||||
this.draw();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
draw: function () {
|
||||
var cc = '"return Base.Comp.get(' + this._cid + ').select()"',
|
||||
st = ' style="color:white;font-size:13px;background-color:#3f7fff;width:100%" ',
|
||||
st2 = ' style="color:white;font-size:13px;background-color:#3f7fff" ',
|
||||
str = '<form name="gsel" onsubmit=' + cc + '><table class="table">'
|
||||
+ '<tr><td colspan="2" style="text-align:center"><b>Game selection</b></td></tr>'
|
||||
+ '<tr><td colspan="2"> </td></tr>'
|
||||
+ '<tr><td><label for="gsel">Game:</label></td>'
|
||||
+ '<td><select name="gsel" id="gsel"' + st;
|
||||
|
||||
for (var i in this.games) {
|
||||
var g = this.games[i];
|
||||
str += '<option value="' + i + '">' + g.name + '</option>';
|
||||
}
|
||||
|
||||
str += '</select></td></tr><tr><td style="text-align:right">'
|
||||
+ '<input type="checkbox" name="grem" id="grem"' + st2 + '/></td>'
|
||||
+ '<td><label for="grem">Remember selection</label></td></tr>'
|
||||
+ '<tr><td colspan="2"> </td></tr>'
|
||||
+ '<tr><td colspan="2"><input type="submit" value="Select this game"'
|
||||
+ st + '</td></tr></table></form>';
|
||||
this.writeContents(str);
|
||||
|
||||
var _cb = document.getElementById('grem');
|
||||
if (_cb) {
|
||||
_cb.checked = (LWWidget.main.getPreference('lwRemGame') == '1');
|
||||
}
|
||||
},
|
||||
|
||||
select: function () {
|
||||
var _s = document.getElementById('gsel');
|
||||
if (!_s) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var sv = parseInt(_s.options[_s.selectedIndex].value, 10), rem = document.getElementById('grem').checked;
|
||||
LWWidget.main.setPreference('lwRemGame', rem ? '1' : '0');
|
||||
if (rem) {
|
||||
LWWidget.main.setPreference('lwGame', this.games[sv].path);
|
||||
}
|
||||
|
||||
this.onSelect(this.games[sv]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,77 +0,0 @@
|
|||
LWWidget.Login = LWWidget.Page.inherits({
|
||||
|
||||
constructor: function () {
|
||||
this.base();
|
||||
this.addEvent('Login');
|
||||
this.error = "";
|
||||
},
|
||||
|
||||
draw: function () {
|
||||
var cc = '"return Base.Comp.get(' + this._cid + ').login()"',
|
||||
st = ' style="color:white;font-size:13px;background-color:#3f7fff;width:100%" ',
|
||||
st2 = ' style="color:white;font-size:13px;background-color:#3f7fff" ',
|
||||
str = '<form name="login" onsubmit=' + cc + '><table class="table">'
|
||||
+ '<tr><td><label for="lname">Username:</label></td><td>'
|
||||
+ '<input type="text" name="lname" id="lname" value=""'
|
||||
+ st + '/></td></tr>'
|
||||
+ '<tr><td><label for="lpass">Password:</label></td><td>'
|
||||
+ '<input type="password" name="lpass" id="lpass" value=""'
|
||||
+ st + '/></td></tr>'
|
||||
+ '<tr><td style="text-align:right"><input type="checkbox" '
|
||||
+ ' name="lrem" id="lrem"' + st2 + '/></td><td>'
|
||||
+ '<label for="lrem">Remember password</label></td></tr>'
|
||||
+ '<tr><td colspan="2"> </td></tr>'
|
||||
+ '<tr><td colspan="2" style="text-align:center" id="lerror"> </td></tr>'
|
||||
+ '<tr><td colspan="2"> </td></tr>'
|
||||
+ '<tr><td colspan="2"><input type="submit" value="Connect to Legacy Worlds!"'
|
||||
+ st + '</td></tr></table></form>';
|
||||
this.writeContents(str);
|
||||
this.fillForm();
|
||||
},
|
||||
|
||||
fillForm: function () {
|
||||
var l = LWWidget.main.getPreference('lwLogin'), p = LWWidget.main.getPreference('lwPassword'), r = LWWidget.main.getPreference('lwRemAuth');
|
||||
if (!document.getElementById('lname')) {
|
||||
return;
|
||||
}
|
||||
document.getElementById('lname').value = l;
|
||||
document.getElementById('lpass').value = p;
|
||||
document.getElementById('lrem').checked = (r == '1');
|
||||
document.getElementById("lerror").innerHTML = (this.error == "") ? ' ' : this.error;
|
||||
},
|
||||
|
||||
|
||||
setError: function (error) {
|
||||
this.error = error;
|
||||
var e = document.getElementById("lerror");
|
||||
if (e) {
|
||||
e.innerHTML = (error == "") ? ' ' : error;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
login: function () {
|
||||
if (!document.getElementById('lname')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var l = document.getElementById('lname').value, p = document.getElementById('lpass').value,
|
||||
r = document.getElementById('lrem').checked ? '1' : '0';
|
||||
|
||||
if (l == '') {
|
||||
this.setError("Please type in your username");
|
||||
} else if (p == '') {
|
||||
this.setError("Please type in your password");
|
||||
} else {
|
||||
// Save the login as a preference and store the rest until we're sure
|
||||
LWWidget.main.setPreference('lwLogin', l);
|
||||
LWWidget.main.setPreference('lwRemAuth', r);
|
||||
LWWidget.main.password = p;
|
||||
|
||||
this.onLogin();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
|
@ -1,392 +0,0 @@
|
|||
LWWidget.Main = Base.Comp.inherits({
|
||||
|
||||
constructor: function () {
|
||||
this.base();
|
||||
|
||||
this.addEvent('Show');
|
||||
this.addEvent('Hide');
|
||||
this.addSlot('draw');
|
||||
this.bindEvent('Show', 'draw');
|
||||
|
||||
// Game-related slots
|
||||
this.addSlot('login');
|
||||
this.addSlot('loadGame');
|
||||
this.addSlot('loadData');
|
||||
|
||||
// Version management slots
|
||||
this.addSlot('versionError');
|
||||
this.addSlot('versionNewAvailable');
|
||||
this.addSlot('versionNewRequired');
|
||||
this.addSlot('versionOk');
|
||||
|
||||
// Generate the menu
|
||||
this.makeMenu();
|
||||
|
||||
// Version checker
|
||||
this.versionCheck = new LWWidget.VersionCheck();
|
||||
this.versionPage = new LWWidget.NewVersion();
|
||||
this.versionCheck.bindEvent('CommError', 'versionError', this);
|
||||
this.versionCheck.bindEvent('NewVersion', 'versionNewAvailable', this);
|
||||
this.versionCheck.bindEvent('RequiredVersion', 'versionNewRequired', this);
|
||||
this.versionCheck.bindEvent('VersionOk', 'versionOk', this);
|
||||
this.versionChecked = false;
|
||||
|
||||
// Login page
|
||||
this.loginPage = new LWWidget.Login();
|
||||
this.loginPage.bindEvent('Login', 'login', this);
|
||||
|
||||
// Game selection page
|
||||
this.gameSelector = new LWWidget.GameSelector();
|
||||
this.gameSelector.bindEvent('Select', 'loadGame', this);
|
||||
|
||||
// Game display
|
||||
this.gameDisplay = new LWWidget.GameDisplay(this);
|
||||
this.gameDisplay.bindEvent('Refresh', 'loadData', this);
|
||||
|
||||
// Generic text display
|
||||
this.textPage = new LWWidget.TextPage();
|
||||
|
||||
// FIXME: Set Dashboard-specific event handlers
|
||||
// this.initDashboard();
|
||||
|
||||
// FIXME: should use saved password if possible
|
||||
this.page = this.loginPage;
|
||||
this.menu.setMode('out');
|
||||
this.state = 0;
|
||||
|
||||
this.onShow(); // FIXME: use Dashboard events if possible
|
||||
},
|
||||
|
||||
|
||||
initDashboard: function () {
|
||||
if (window.widget) {
|
||||
var _cid = this._cid;
|
||||
widget.onshow = function () {
|
||||
if (Base) {
|
||||
Base.Comp.get(_cid).onShow();
|
||||
}
|
||||
};
|
||||
widget.onhide = function () {
|
||||
if (Base) {
|
||||
Base.Comp.get(_cid).onHide();
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
makeMenu: function () {
|
||||
var _m;
|
||||
this.menu = new LWWidget.Menu();
|
||||
this.addSlot('menuCommand');
|
||||
this.menu.bindEvent('Click', 'menuCommand', this);
|
||||
|
||||
// Waiting
|
||||
_m = this.menu.newMode('wait');
|
||||
_m.addItem(new LWWidget.Menu.Text('Loading ... Please wait ...'));
|
||||
|
||||
// New version available
|
||||
_m = this.menu.newMode('nvAvail');
|
||||
_m.addItem(new LWWidget.Menu.Text('New version! '));
|
||||
_m.addItem(new LWWidget.Menu.Command('continue', 'Continue'));
|
||||
_m.addItem(new LWWidget.Menu.Command('logout', 'Log out'));
|
||||
|
||||
// New version required
|
||||
_m = this.menu.newMode('nvReq');
|
||||
_m.addItem(new LWWidget.Menu.Text('Update required '));
|
||||
_m.addItem(new LWWidget.Menu.Command('logout', 'Log out'));
|
||||
|
||||
// Logged out user
|
||||
_m = this.menu.newMode('out');
|
||||
_m.addItem(new LWWidget.Menu.Text('Please log in'));
|
||||
|
||||
// Game selection
|
||||
_m = this.menu.newMode('game');
|
||||
_m.addItem(new LWWidget.Menu.Entry('gamesel', 'Game selection'));
|
||||
_m.addItem(new LWWidget.Menu.Command('logout', 'Log out'));
|
||||
|
||||
// Error
|
||||
_m = this.menu.newMode('error');
|
||||
_m.addItem(new LWWidget.Menu.Text('Error! - '));
|
||||
_m.addItem(new LWWidget.Menu.Command('logout', 'Log out'));
|
||||
|
||||
// Standard
|
||||
_m = this.menu.newMode('std');
|
||||
_m.addItem(new LWWidget.Menu.Command('gamesel', 'Game selection'));
|
||||
_m.addItem(new LWWidget.Menu.Entry('player', 'Player'));
|
||||
_m.addItem(new LWWidget.Menu.Entry('planets', 'Planets'));
|
||||
_m.addItem(new LWWidget.Menu.Entry('fleets', 'Fleets'));
|
||||
_m.addItem(new LWWidget.Menu.Entry('budget', 'Budget'));
|
||||
_m.addItem(new LWWidget.Menu.Entry('tech', 'Research'));
|
||||
_m.addItem(new LWWidget.Menu.Entry('msg', 'Messages'));
|
||||
_m.addItem(new LWWidget.Menu.Entry('forums', 'Forums'));
|
||||
_m.addItem(new LWWidget.Menu.Entry('ticks', 'Ticks'));
|
||||
_m.addItem(new LWWidget.Menu.Command('logout', 'Log out'));
|
||||
},
|
||||
|
||||
|
||||
initLoader: function (login, password) {
|
||||
this.loader = new LWWidget.Data.Loader(LWWidget.main.getPreference('lwLogin'), LWWidget.main.password);
|
||||
|
||||
var events = ['CommError', 'FatalError', 'Kick', 'Load', 'LoginFailure', 'Maintenance', 'Destroy'];
|
||||
var slots = ['commError', 'serverError', 'playerKicked', 'dataLoaded', 'loginFailed', 'serverMaintenance', 'loaderDestroyed'];
|
||||
for (var i=0;i<events.length;i++) {
|
||||
this.addSlot(slots[i]);
|
||||
this.loader.bindEvent(events[i], slots[i], this);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
draw: function () {
|
||||
var c = LWWidget.main.getPreference('lwColour');
|
||||
var str = '<img src="images/' + c + '.png" />'
|
||||
+ '<div id="mainDiv"><table id="mainTable">'
|
||||
+ '<tr><td id="mtTitle">Legacy Worlds</td></tr>'
|
||||
+ '<tr><td id="mtMenu"> </td></tr>'
|
||||
+ '<tr><td id="mtContents"> </td></tr>'
|
||||
+ '</table></div>';
|
||||
if (LWWidget.debug) {
|
||||
str += '<div id="debugDiv"> </div><div id="debugLink"><a href="#" onclick="LWWidget.main.showDebug();return false">Debug mode</a></div>';
|
||||
}
|
||||
Base.Browser.get().docBody.innerHTML = str;
|
||||
|
||||
this.menu.draw();
|
||||
this.page.draw();
|
||||
},
|
||||
|
||||
|
||||
setTextPage: function (mMode, text) {
|
||||
this.menu.setMode(mMode);
|
||||
this.page = this.textPage;
|
||||
this.page.setText(text);
|
||||
},
|
||||
|
||||
menuCommand: function (command) {
|
||||
if (command == 'logout') {
|
||||
if (this.loader) {
|
||||
this.loader.destroy();
|
||||
}
|
||||
if (this.versionCheck) {
|
||||
this.versionCheck.stop();
|
||||
}
|
||||
if (this.state == 3) {
|
||||
this.gameDisplay.hide();
|
||||
}
|
||||
this.state = 0;
|
||||
this.versionChecked = false;
|
||||
this.loginPage.setError('');
|
||||
this.page = this.loginPage;
|
||||
this.menu.setMode('out');
|
||||
this.page.draw();
|
||||
} else if (command == 'continue') {
|
||||
this.login();
|
||||
} else if (command == 'gamesel') {
|
||||
if (this.state == 3) {
|
||||
this.page.hide();
|
||||
}
|
||||
this.state = 1;
|
||||
this.setTextPage('wait', 'Connecting to the Legacy Worlds server<br/><br/>Please wait');
|
||||
this.loader.load('main/index');
|
||||
} else if (this.state == 3) {
|
||||
this.gameDisplay.setPage(command);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
versionError: function () {
|
||||
// Ignore the error if the version has already been checked
|
||||
if (!this.versionChecked) {
|
||||
this.commError();
|
||||
}
|
||||
},
|
||||
|
||||
versionNewAvailable: function (url) {
|
||||
// Ignore the new version unless it is the first time we check
|
||||
if (this.versionChecked) {
|
||||
return;
|
||||
}
|
||||
this.versionChecked = true;
|
||||
|
||||
this.versionPage.setData(url, false);
|
||||
this.page = this.versionPage;
|
||||
this.menu.setMode('nvAvail');
|
||||
this.page.draw();
|
||||
},
|
||||
|
||||
versionNewRequired: function (url) {
|
||||
if (this.state == 3) {
|
||||
this.gameDisplay.hide();
|
||||
}
|
||||
this.versionCheck.stop();
|
||||
this.versionPage.setData(url, true);
|
||||
this.page = this.versionPage;
|
||||
this.menu.setMode('nvReq');
|
||||
this.page.draw();
|
||||
},
|
||||
|
||||
versionOk: function () {
|
||||
if (!this.versionChecked) {
|
||||
// Continue login
|
||||
this.versionChecked = true;
|
||||
this.login();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
login: function () {
|
||||
this.setTextPage('wait', 'Connecting to the Legacy Worlds server<br/><br/>Please wait');
|
||||
|
||||
// If the version hasn't been checked, well, check it
|
||||
if (!this.versionChecked) {
|
||||
this.versionCheck.start();
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialise the loader and get the game list
|
||||
this.initLoader();
|
||||
this.loader.load('main/index');
|
||||
},
|
||||
|
||||
|
||||
handleGameList: function (data, force) {
|
||||
this.state = 1;
|
||||
|
||||
var games = new Array(), auto = null;
|
||||
|
||||
if (!force && LWWidget.main.getPreference('lwRemGame') == '1') {
|
||||
auto = LWWidget.main.getPreference('lwGame');
|
||||
}
|
||||
|
||||
for (var i in data.contents) {
|
||||
// Check if version is supported
|
||||
var _v = data.contents[i].getAttribute('version');
|
||||
if (!LWWidget.Game.versions().containsKey(_v)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var _g = {
|
||||
name: data.contents[i].getText(),
|
||||
path: data.contents[i].getAttribute('path'),
|
||||
version: LWWidget.Game.versions().get(_v)
|
||||
};
|
||||
if (auto && auto == _g.path) {
|
||||
this.loadGame(_g);
|
||||
return;
|
||||
}
|
||||
games.push(_g);
|
||||
}
|
||||
|
||||
if (games.length == 0) {
|
||||
this.setTextPage('error', 'It appears that you are not registered to any Legacy Worlds game.');
|
||||
} else if (!force && games.length == 1) {
|
||||
this.loadGame(games[0]);
|
||||
} else {
|
||||
this.page = this.gameSelector;
|
||||
this.menu.setMode('game');
|
||||
this.gameSelector.setGames(games);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
loadGame: function (game) {
|
||||
this.state = 2;
|
||||
this.currentGame = game;
|
||||
this.loader.load(game.path + '/play');
|
||||
},
|
||||
|
||||
loadData: function (path) {
|
||||
if (this.state == 3 && this.loader) {
|
||||
this.loader.load(path + '/play');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
commError: function () {
|
||||
this.setTextPage('error', '<b>Communications error</b><br/><br/>The server could not be reached or it sent an invalid reply.');
|
||||
},
|
||||
|
||||
serverError: function (code, text) {
|
||||
var str = '<b>Server error</b><br/><br/>The server encountered an internal error:<br/><i>'
|
||||
+ text + '</i><br/>(code: ' + code + ')';
|
||||
this.setTextPage('error', str);
|
||||
},
|
||||
|
||||
playerKicked: function (reason) {
|
||||
var str = (reason == '' ? 'No reason was specified' : ('<b>Reason:</b> ' + reason));
|
||||
if (this.state == 3) {
|
||||
this.gameDisplay.hide();
|
||||
}
|
||||
this.setTextPage('error', 'You have been <b>kicked</b> from the game!<br/><br/>' + str);
|
||||
},
|
||||
|
||||
loginFailed: function (code) {
|
||||
switch (code) {
|
||||
case '0':
|
||||
if (this.state == 0) {
|
||||
this.loader.destroy();
|
||||
LWWidget.main.password = '';
|
||||
this.loginPage.setError('Invalid username or password');
|
||||
this.page = this.loginPage;
|
||||
this.page.draw();
|
||||
} else {
|
||||
this.setTextPage('error', 'Your password has been changed.');
|
||||
}
|
||||
break;
|
||||
case '1':
|
||||
this.setTextPage('error', 'The server encountered an internal error while authenticating your account.');
|
||||
break;
|
||||
case '2':
|
||||
this.setTextPage('error', 'Your account has been closed!');
|
||||
break;
|
||||
case '3':
|
||||
this.setTextPage('error', 'Your account has not been validated yet, please check your e-mail.');
|
||||
break;
|
||||
case '4':
|
||||
if (this.state < 2) {
|
||||
this.setTextPage('error', 'The server just did something it\'s not supposed to do. Ever.');
|
||||
} else {
|
||||
this.gameDisplay.hide();
|
||||
this.setTextPage('errsel', 'You are no longer registered to this game!');
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
serverMaintenance: function (reason, until, now) {
|
||||
var str = '<b>The server is undergoing maintenance.</b><br/><br/>Reason: ' + reason
|
||||
+ '<br/><br/>It will be down until <b>' + until + '</b>.<br/>Current server time: ' + now;
|
||||
this.setTextPage('error', str);
|
||||
},
|
||||
|
||||
loaderDestroyed: function () {
|
||||
this.loader = null;
|
||||
},
|
||||
|
||||
dataLoaded: function (data) {
|
||||
if (this.state == 0) {
|
||||
// We were not loging in, save password if needed
|
||||
if (LWWidget.main.getPreference('lwRemAuth') == '1') {
|
||||
LWWidget.main.setPreference('lwPassword', LWWidget.main.password);
|
||||
}
|
||||
|
||||
this.handleGameList(data);
|
||||
} else if (this.state == 1) {
|
||||
// We were logged in but asked to select a game
|
||||
this.handleGameList(data, true);
|
||||
} else if (this.state == 2) {
|
||||
// We just received game data for the first time
|
||||
this.gameDisplay.setGame(this.currentGame.version, this.currentGame.path);
|
||||
this.gameDisplay.handleData(data);
|
||||
this.page = this.gameDisplay;
|
||||
this.menu.setMode('std');
|
||||
this.menu.setSelected('player');
|
||||
this.page.draw();
|
||||
this.state = 3;
|
||||
} else {
|
||||
// Update game contents
|
||||
this.gameDisplay.handleData(data);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
|
@ -1,81 +0,0 @@
|
|||
LWWidget.Menu = Base.Comp.inherits({
|
||||
|
||||
constructor: function () {
|
||||
this.base();
|
||||
|
||||
this.currentMode = null;
|
||||
this.modes = new Base.Util.Hashtable();
|
||||
|
||||
this.addSlot('modeDestroyed');
|
||||
this.addSlot('draw');
|
||||
this.addEvent('Click');
|
||||
this.bindEvent('Click', 'draw');
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
var modes = this.modes.values();
|
||||
for (var i in modes) {
|
||||
modes[i].destroy();
|
||||
}
|
||||
this.base();
|
||||
},
|
||||
|
||||
|
||||
newMode: function (name) {
|
||||
if (this.modes.containsKey(name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var mode = new LWWidget.Menu.Mode(name);
|
||||
this.modes.put(name, mode);
|
||||
if (!this.currentMode) {
|
||||
this.currentMode = mode;
|
||||
}
|
||||
|
||||
mode.bindEvent('Destroy', 'modeDestroyed', this);
|
||||
mode.bindEvent('Click', 'onClick', this);
|
||||
|
||||
return mode;
|
||||
},
|
||||
|
||||
setMode: function (name) {
|
||||
if (!this.modes.containsKey(name) || this.currentMode && this.currentMode.name == name) {
|
||||
return;
|
||||
}
|
||||
this.currentMode = this.modes.get(name);
|
||||
this.draw();
|
||||
},
|
||||
|
||||
setSelected: function (name) {
|
||||
if (this.currentMode) {
|
||||
this.currentMode.setSelected(name);
|
||||
this.draw();
|
||||
}
|
||||
},
|
||||
|
||||
modeDestroyed: function (mode) {
|
||||
if (!(mode && mode._cid && mode.name && this.modes.containsKey(mode.name))) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.modes.remove(mode.name);
|
||||
if (this.currentMode && this.currentMode._cid == mode._cid) {
|
||||
var _v = this.modes.values();
|
||||
if (_v.length) {
|
||||
this.currentMode = _v[0];
|
||||
} else {
|
||||
this.currentMode = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
draw: function () {
|
||||
var e = document.getElementById('mtMenu');
|
||||
if (!(e && this.currentMode)) {
|
||||
return;
|
||||
}
|
||||
e.innerHTML = this.currentMode.draw();
|
||||
}
|
||||
|
||||
});
|
|
@ -1,7 +0,0 @@
|
|||
LWWidget.Menu.Command = LWWidget.Menu.Item.inherits({
|
||||
|
||||
constructor: function (name, text) {
|
||||
this.base(name, text, true, false, ' - ');
|
||||
}
|
||||
|
||||
});
|
|
@ -1,7 +0,0 @@
|
|||
LWWidget.Menu.Entry = LWWidget.Menu.Item.inherits({
|
||||
|
||||
constructor: function (name, text) {
|
||||
this.base(name, text, true, true, ' - ');
|
||||
}
|
||||
|
||||
});
|
|
@ -1,38 +0,0 @@
|
|||
LWWidget.Menu.Item = Base.Comp.inherits({
|
||||
|
||||
constructor: function (name, text, clickable, selectable, separator) {
|
||||
this.base();
|
||||
|
||||
this.name = name;
|
||||
this.text = text;
|
||||
this.clickable = !!clickable;
|
||||
this.selectable = this.clickable && !!selectable;
|
||||
this.separator = (typeof separator == 'string') ? separator : '';
|
||||
this.selected = false;
|
||||
|
||||
this.addEvent('Click');
|
||||
},
|
||||
|
||||
draw: function () {
|
||||
var pfx, sfx;
|
||||
if (this.clickable && !this.selected) {
|
||||
pfx = '<a href="#" onclick="Base.Comp.get(' + this._cid + ').click();return false">';
|
||||
sfx = '</a>';
|
||||
} else if (this.selectable && this.selected) {
|
||||
pfx = '<b>';
|
||||
sfx = '</b>';
|
||||
} else {
|
||||
pfx = sfx = '';
|
||||
}
|
||||
|
||||
return pfx + this.text + sfx;
|
||||
},
|
||||
|
||||
click: function () {
|
||||
if (this.selectable) {
|
||||
this.selected = true;
|
||||
}
|
||||
this.onClick(this);
|
||||
}
|
||||
|
||||
});
|
|
@ -1,109 +0,0 @@
|
|||
LWWidget.Menu.Mode = Base.Comp.inherits({
|
||||
|
||||
constructor: function (name) {
|
||||
this.base();
|
||||
|
||||
this.name = name;
|
||||
this.items = new Base.Util.Hashtable();
|
||||
this.selected = null;
|
||||
|
||||
this.addSlot('itemDestroyed');
|
||||
this.addSlot('itemClicked');
|
||||
this.addEvent('Click');
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
var items = this.items.values();
|
||||
for (var i in items) {
|
||||
var _i = items[i];
|
||||
this.items.remove(items[i]._cid);
|
||||
items[i].destroy();
|
||||
}
|
||||
|
||||
this.base();
|
||||
},
|
||||
|
||||
draw: function () {
|
||||
var str = '', items = this.items.values();
|
||||
|
||||
for (var i=0;i<items.length;i++) {
|
||||
str += items[i].draw();
|
||||
if (i < items.length - 1 && items[i].separator) {
|
||||
str += items[i].separator;
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
|
||||
|
||||
addItem: function (item) {
|
||||
if (!(item && item._cid) || this.items.containsKey(item._cid)) {
|
||||
return;
|
||||
}
|
||||
this.items.put(item._cid, item);
|
||||
if (item.selectable && !this.selected) {
|
||||
item.selected = true;
|
||||
this.selected = item;
|
||||
} else {
|
||||
item.selected = false;
|
||||
}
|
||||
|
||||
item.bindEvent('Destroy', 'itemDestroyed', this);
|
||||
item.bindEvent('Click', 'itemClicked', this);
|
||||
},
|
||||
|
||||
|
||||
setSelected: function (name) {
|
||||
var _k = this.items.values();
|
||||
for (var i in _k) {
|
||||
var item = _k[i];
|
||||
if (item.selectable && item.name == name) {
|
||||
if (this.selected) {
|
||||
if (this.selected._cid == item._cid) {
|
||||
return;
|
||||
}
|
||||
this.selected.selected = false;
|
||||
}
|
||||
item.selected = true;
|
||||
this.selected = item;
|
||||
return;
|
||||
} else if (item.name == name) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
itemClicked: function (item) {
|
||||
if (item.selectable) {
|
||||
if (this.selected) {
|
||||
this.selected.selected = false;
|
||||
}
|
||||
item.selected = true;
|
||||
this.selected = item;
|
||||
}
|
||||
this.onClick(item.name);
|
||||
},
|
||||
|
||||
itemDestroyed: function (item) {
|
||||
if (!(item && item._cid && this.items.containsKey(item._cid))) {
|
||||
return;
|
||||
}
|
||||
this.items.remove(item._cid);
|
||||
|
||||
if (this.selected && this.selected._cid == item._cid) {
|
||||
var _v = this.items.values(), _s = null;
|
||||
for (var i in _v) {
|
||||
var _i = _v[i];
|
||||
if (_i.selectable) {
|
||||
_s = _i;
|
||||
_i.selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.selected = _s;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
|
@ -1,7 +0,0 @@
|
|||
LWWidget.Menu.Text = LWWidget.Menu.Item.inherits({
|
||||
|
||||
constructor: function (text) {
|
||||
this.base('', text);
|
||||
}
|
||||
|
||||
});
|
|
@ -1,33 +0,0 @@
|
|||
LWWidget.NewVersion = LWWidget.Page.inherits({
|
||||
|
||||
setData: function (url, required) {
|
||||
this.url = url;
|
||||
this.required = required;
|
||||
},
|
||||
|
||||
|
||||
draw: function () {
|
||||
var _s;
|
||||
|
||||
if (this.required) {
|
||||
_s = 'Due to server updates, you are required to download a new version of this widget in order to keep using it.';
|
||||
} else {
|
||||
_s = 'A new version of the LegacyWorlds widget is available!<br/><br/>'
|
||||
+ 'Upgrading the widget is not mandatory; the new version only brings new features and bugfixes.';
|
||||
}
|
||||
|
||||
_s += '<br/><br/><a href="#" onclick="Base.Comp.get(' + this._cid + ').startDownload();return false">Download the new version</a>';
|
||||
|
||||
this.writeContents(_s);
|
||||
},
|
||||
|
||||
|
||||
startDownload: function () {
|
||||
if (window.widget) {
|
||||
widget.openURL(this.url);
|
||||
} else {
|
||||
window.open(this.url);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
|
@ -1,17 +0,0 @@
|
|||
LWWidget.Page = Base.Comp.inherits({
|
||||
|
||||
constructor: function () {
|
||||
this.base();
|
||||
|
||||
this.addEvent('Show');
|
||||
this.addEvent('Hide');
|
||||
},
|
||||
|
||||
writeContents: function (contents) {
|
||||
var e = document.getElementById('mtContents');
|
||||
if (e) {
|
||||
e.innerHTML = contents;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
|
@ -1,18 +0,0 @@
|
|||
LWWidget.TextPage = LWWidget.Page.inherits({
|
||||
|
||||
constructor: function () {
|
||||
this.text = "";
|
||||
},
|
||||
|
||||
setText: function (text) {
|
||||
if (this.text != text) {
|
||||
this.text = text;
|
||||
}
|
||||
this.draw();
|
||||
},
|
||||
|
||||
draw: function () {
|
||||
this.writeContents(this.text == "" ? ' ' : this.text);
|
||||
}
|
||||
|
||||
});
|
|
@ -1,101 +0,0 @@
|
|||
LWWidget.VersionCheck = Base.Comp.inherits({
|
||||
|
||||
constructor: function () {
|
||||
this.base();
|
||||
|
||||
this.addEvent('CommError');
|
||||
this.addEvent('NewVersion');
|
||||
this.addEvent('RequiredVersion');
|
||||
this.addEvent('VersionOk');
|
||||
|
||||
this.addSlot('dataReceived');
|
||||
this.addSlot('loaderDestroyed');
|
||||
this.addSlot('timerDestroyed');
|
||||
|
||||
this.loader = new Base.XMLLoader(LWWidget.base + '/index.php/main/macwidget.xml', false);
|
||||
this.loader.bindEvent('Destroy', 'loaderDestroyed', this);
|
||||
this.loader.bindEvent('NetworkError', 'onCommError', this);
|
||||
this.loader.bindEvent('ServerError', 'onCommError', this);
|
||||
this.loader.bindEvent('Timeout', 'onCommError', this);
|
||||
this.loader.bindEvent('Unsupported', 'onCommError', this);
|
||||
this.loader.bindEvent('Aborted', 'onCommError', this);
|
||||
this.loader.bindEvent('Loaded', 'dataReceived', this);
|
||||
|
||||
this.timer = new Base.Timer(300000, true);
|
||||
this.timer.bindEvent('Tick', 'load', this.loader);
|
||||
this.timer.bindEvent('Destroy', 'timerDestroyed', this);
|
||||
|
||||
this.knownVersion = LWWidget.version;
|
||||
},
|
||||
|
||||
|
||||
destroy: function () {
|
||||
if (this.loader) {
|
||||
this.loader.destroy();
|
||||
}
|
||||
if (this.timer) {
|
||||
this.timer.destroy();
|
||||
}
|
||||
this.base();
|
||||
},
|
||||
|
||||
|
||||
timerDestroyed: function () {
|
||||
this.timer = null;
|
||||
},
|
||||
|
||||
loaderDestroyed: function () {
|
||||
this.loader = null;
|
||||
},
|
||||
|
||||
|
||||
start: function () {
|
||||
if (typeof this.requiredVersion != 'undefined' && LWWidget.version < this.requiredVersion) {
|
||||
return;
|
||||
}
|
||||
this.timer.start();
|
||||
this.loader.load();
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
this.timer.stop();
|
||||
this.knownVersion = LWWidget.version;
|
||||
delete this.latestVersion;
|
||||
delete this.requiredVersion;
|
||||
},
|
||||
|
||||
|
||||
dataReceived: function (data) {
|
||||
var _xml = Base.Util.parseXML(data);
|
||||
if (!_xml) {
|
||||
this.onCommError();
|
||||
return;
|
||||
}
|
||||
|
||||
var _doc = _xml.documentElement;
|
||||
this.latestVersion = parseInt(_doc.getAttribute('latest'), 10);
|
||||
this.requiredVersion = parseInt(_doc.getAttribute('oldestOk'), 10);
|
||||
this.url = _doc.childNodes[0].nodeValue;
|
||||
|
||||
if (this.knownVersion == this.latestVersion && this.requiredVersion <= LWWidget.version) {
|
||||
this.onVersionOk();
|
||||
return;
|
||||
}
|
||||
|
||||
Base.Log.write('Version check: current version = ' + LWWidget.version);
|
||||
Base.Log.write('Version check: latest received version = ' + this.knownVersion);
|
||||
Base.Log.write('Version check: latest version = ' + this.latestVersion);
|
||||
Base.Log.write('Version check: oldest accepted version = ' + this.requiredVersion);
|
||||
|
||||
this.knownVersion = this.latestVersion;
|
||||
if (LWWidget.version < this.requiredVersion) {
|
||||
this.onRequiredVersion(this.url);
|
||||
this.timer.stop();
|
||||
} else if (LWWidget.version < this.latestVersion) {
|
||||
this.onNewVersion(this.url);
|
||||
} else {
|
||||
this.onVersionOk();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
|
@ -1,2 +0,0 @@
|
|||
LWWidget.Versions = new Base.Util.Hashtable();
|
||||
LWWidget.Versions.put('beta5', LWWidget.Beta5);
|
|
@ -4,18 +4,12 @@
|
|||
// engine instance
|
||||
|
||||
$config = array(
|
||||
// Database connection parameters
|
||||
"dbhost" => "localhost",
|
||||
"dbuser" => "legacy",
|
||||
"dbpass" => "",
|
||||
"dbname" => "legacy",
|
||||
|
||||
// Path and URL to static contents
|
||||
"staticdir" => dirname(__FILE__) . "/../site/static",
|
||||
"staticurl" => "http://www.legacyworlds.com/static",
|
||||
"staticdir" => __DIR__ . "/../site/static",
|
||||
"staticurl" => "http://localhost/static",
|
||||
|
||||
// Path to game scripts
|
||||
"scriptdir" => dirname(__FILE__),
|
||||
"scriptdir" => __DIR__,
|
||||
|
||||
// Path to the cache
|
||||
"cachedir" => "/tmp/lwcache",
|
||||
|
@ -33,11 +27,6 @@ $config = array(
|
|||
),
|
||||
*/
|
||||
|
||||
// Mac widget version numbers and location
|
||||
"latestWidget" => 1,
|
||||
"oldestWidget" => 1,
|
||||
"widgetURL" => "http://www.legacyworlds.com/downloads/LegacyWorlds-Dashboard-latest.zip",
|
||||
|
||||
// Version numbers to make us feel good
|
||||
"v_engine" => "0.85a",
|
||||
"v_game" => "Beta 5",
|
||||
|
|
|
@ -150,14 +150,6 @@ class main_ticks_deathofrats_library {
|
|||
l::debug("Analysing " . count($this->connections) . " new record(s)");
|
||||
$this->makePerAccountRecords();
|
||||
|
||||
// Start with open proxies
|
||||
l::debug("Checking for open proxies ...");
|
||||
$this->checkOpenProxies();
|
||||
if ($this->proxiedAccounts) {
|
||||
l::info("Logging " . count($this->proxiedAccounts) . " account(s) using open proxies");
|
||||
$this->db->safeTransaction(array($this, 'logOpenProxies'));
|
||||
}
|
||||
|
||||
// Now examine per-account entries to find different types of rats
|
||||
l::debug("Checking single player badness");
|
||||
foreach ($this->perAccount as $records) {
|
||||
|
@ -660,111 +652,6 @@ class main_ticks_deathofrats_library {
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* OPEN PROXIES *
|
||||
***********************************************************************/
|
||||
|
||||
/** This method checks for open proxies in the latest log entries.
|
||||
*/
|
||||
private function checkOpenProxies() {
|
||||
$IPs = array();
|
||||
|
||||
// Make lists of accounts for each IP
|
||||
foreach ($this->connections as $record) {
|
||||
if ($record['ip_addr'] == 'AUTO' || $record['action'] == 'OUT') {
|
||||
continue;
|
||||
}
|
||||
$ip = $record['ip_addr'];
|
||||
$account = $record['account'];
|
||||
if (!is_array($IPs[$ip])) {
|
||||
$IPs[$ip] = array($account);
|
||||
} elseif (!in_array($account, $IPs[$ip])) {
|
||||
array_push($IPs[$ip], $account);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for proxies on the IPs
|
||||
$requests = array();
|
||||
$proxies = array();
|
||||
foreach (array_keys($IPs) as $ip) {
|
||||
if (count($requests) < 20) {
|
||||
array_push($requests, $ip);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$results = pcheck::check($requests);
|
||||
} catch (Exception $e) {
|
||||
l::error("Failed to check some addresses for open proxies");
|
||||
l::info($e->getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($results as $host => $status) {
|
||||
if ($status == 1) {
|
||||
array_push($proxies, $host);
|
||||
}
|
||||
}
|
||||
|
||||
$requests = array();
|
||||
}
|
||||
|
||||
// If there are some requests we didn't execute, do it
|
||||
if (count($requests)) {
|
||||
try {
|
||||
$results = pcheck::check($requests);
|
||||
} catch (Exception $e) {
|
||||
l::error("Failed to check some addresses for open proxies");
|
||||
l::info($e->getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($results as $host => $status) {
|
||||
if ($status == 1) {
|
||||
array_push($proxies, $host);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for proxied accounts
|
||||
$proxyAccounts = array();
|
||||
foreach ($proxies as $ip) {
|
||||
foreach ($IPs[$ip] as $account) {
|
||||
if (in_array($account, $proxyAccounts)) {
|
||||
continue;
|
||||
}
|
||||
array_push($proxyAccounts, $account);
|
||||
}
|
||||
}
|
||||
|
||||
$this->proxiedAccounts = $proxyAccounts;
|
||||
}
|
||||
|
||||
|
||||
/** This method logs access to accounts using open proxies. A log
|
||||
* entry is only added every 24h.
|
||||
*/
|
||||
public function logOpenProxies() {
|
||||
// Get all recent open proxy logs
|
||||
$this->db->query(
|
||||
"SELECT account FROM dor_single "
|
||||
. "WHERE message = 'PROXY' AND {$this->now} - ts < 86400"
|
||||
);
|
||||
$recent = array();
|
||||
while ($r = dbFetchArray($q)) {
|
||||
$recent[] = $r[0];
|
||||
}
|
||||
|
||||
// Insert proxy logs
|
||||
foreach ($this->proxiedAccounts as $account) {
|
||||
if (in_array($account, $recent)) {
|
||||
continue;
|
||||
}
|
||||
$this->singlePlayerLog("PROXY", $account);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SINGLE PLAYER SUSPICIOUS BEHAVIOUR *
|
||||
***********************************************************************/
|
||||
|
|
|
@ -15,17 +15,6 @@
|
|||
|
||||
<!-- Planet generator script -->
|
||||
<Param name="pgenreq" value="/tmp/pgen" />
|
||||
|
||||
<!-- MacOS Dashboard widget -->
|
||||
<Param name="latestWidget" value="1" />
|
||||
<Param name="oldestWidget" value="1" />
|
||||
<Param name="widgetURL" value="http://www.legacyworlds.com/downloads/LegacyWorlds-Dashboard-latest.zip" />
|
||||
|
||||
<!-- Proxy detector -->
|
||||
<Param name="pcheck_server" value="www.legacyworlds.com" />
|
||||
<Param name="pcheck_path" value="/index.php/main/pcheck" />
|
||||
<Param name="pcheck_timeout" value="3" />
|
||||
<Param name="pcheck_threads" value="20" />
|
||||
</MainParams>
|
||||
|
||||
<!-- This part configures the general ticks that are not related to a
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
<?php
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// LegacyWorlds Beta 5
|
||||
// Game libraries
|
||||
//
|
||||
// lib/pcheck.inc
|
||||
//
|
||||
// This library allows access to the proxy detector.
|
||||
//
|
||||
// Copyright(C) 2004-2008, DeepClone Development
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
class pcheck {
|
||||
|
||||
private static $queue = null;
|
||||
private static $pid = null;
|
||||
|
||||
public static function isRunning() {
|
||||
$fName = config::$main['cs_path'] . "/proxyDetector.pid";
|
||||
if (!file_exists($fName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = fopen($fName, "r");
|
||||
$line = rtrim(fgets($file));
|
||||
fclose($file);
|
||||
|
||||
list($pid, $time) = explode(" ", $line);
|
||||
if (time() - $time > 22) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $pid;
|
||||
}
|
||||
|
||||
private static function getQueue() {
|
||||
if (! is_null(self::$queue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$key = ftok(config::$main['scriptdir'] . "/lib/pcheck_manager.inc", "C");
|
||||
if ($key == -1) {
|
||||
throw new Exception("Could not create the control queue's key");
|
||||
}
|
||||
|
||||
self::$queue = @msg_get_queue($key);
|
||||
if (self::$queue === FALSE) {
|
||||
self::$queue = null;
|
||||
throw new Exception("Could not access the control queue (using key $key)");
|
||||
}
|
||||
|
||||
self::$pid = posix_getpid();
|
||||
}
|
||||
|
||||
private static function sendRequest($addresses) {
|
||||
array_unshift($addresses, self::$pid);
|
||||
if (!@msg_send(self::$queue, 1, $addresses, true, false)) {
|
||||
throw new Exception("Error while sending request");
|
||||
}
|
||||
}
|
||||
|
||||
private static function getResults() {
|
||||
$wait = 30;
|
||||
do {
|
||||
$success = @msg_receive(self::$queue, self::$pid, $type, 32768, $result,
|
||||
true, MSG_IPC_NOWAIT, $error);
|
||||
|
||||
if (!$success && $error != MSG_ENOMSG) {
|
||||
throw new Exception("Error while waiting for results");
|
||||
} elseif ($success) {
|
||||
if (is_array($result)) {
|
||||
return $result;
|
||||
} elseif ($result == 'PING') {
|
||||
$wait = 30;
|
||||
} else {
|
||||
throw new Exception("Invalid message received");
|
||||
}
|
||||
} else {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
$wait --;
|
||||
|
||||
} while ($wait);
|
||||
|
||||
throw new Exception("Timeout while waiting for results");
|
||||
}
|
||||
|
||||
public static function check($addresses, $force = false) {
|
||||
if (!($force || self::isRunning())) {
|
||||
throw new Exception("The detector doesn't seem to be running");
|
||||
}
|
||||
self::getQueue();
|
||||
self::sendRequest($addresses);
|
||||
return self::getResults();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
|
@ -1,629 +0,0 @@
|
|||
<?php
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// LegacyWorlds Beta 5
|
||||
// Game libraries
|
||||
//
|
||||
// lib/pcheck_manager.inc
|
||||
//
|
||||
// This library contains the code of the open proxy detector's main
|
||||
// thread.
|
||||
//
|
||||
// Copyright(C) 2004-2008, DeepClone Development
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
|
||||
declare(ticks = 1); // PHP stupidity
|
||||
|
||||
|
||||
class pcheck_manager {
|
||||
|
||||
/** This property indicates how many of the threads are free.
|
||||
*/
|
||||
private $nFree;
|
||||
|
||||
/** These properties are accessed by the detection threads to
|
||||
* read their parameters.
|
||||
*/
|
||||
public static $timeout;
|
||||
public static $requests;
|
||||
|
||||
|
||||
/** This property points to the only current instance of the
|
||||
* proxy detector.
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/** This property indicates whether the manager is being run in
|
||||
* debugging mode.
|
||||
*/
|
||||
private $debug;
|
||||
|
||||
/** This property contains the objects corresponding to each thread.
|
||||
*/
|
||||
private $threads = array();
|
||||
|
||||
/** This property is set to true when the manager is shutting down.
|
||||
*/
|
||||
private $ending = false;
|
||||
|
||||
/** Ports to scan on.
|
||||
*/
|
||||
static private $ports = array(
|
||||
80, 81, 1075, 3128, 4480, 5490, 6588, 7033, 8000,
|
||||
8080, 8081, 8085, 8090, 8095, 8100, 8105, 8110
|
||||
);
|
||||
|
||||
|
||||
/** This method sends commands to the FIFO controller. If the manager
|
||||
* is being run in debugging mode, the commands are not sent.
|
||||
*/
|
||||
private static function sendToControl($command) {
|
||||
if (self::$instance->debug) {
|
||||
return;
|
||||
}
|
||||
$pipe = fopen(config::$main['cs_fifo'], "w");
|
||||
fwrite($pipe, "$command\n");
|
||||
fclose($pipe);
|
||||
}
|
||||
|
||||
|
||||
/** This method is called by the error manager in case a fatal error
|
||||
* prevents the manager from functionning properly.
|
||||
*/
|
||||
public static function fatalError($errno, $errorText, $information) {
|
||||
$instance->shutdown();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/** The constructor forks, initialises the message queues, starts
|
||||
* the detector threads then calls waitForInstructions(). It never
|
||||
* returns.
|
||||
*/
|
||||
public function __construct($debug) {
|
||||
self::$instance = $this;
|
||||
$this->debug = $debug;
|
||||
|
||||
$this->backgroundProcess();
|
||||
$this->initMessageQueues();
|
||||
$this->initSignals();
|
||||
$this->initData();
|
||||
$this->initThreads();
|
||||
$this->initCache();
|
||||
|
||||
// Sends our PID to the controller
|
||||
self::sendToControl("PCPID " . ($this->pid = posix_getpid()));
|
||||
|
||||
l::notice("Proxy detector initialised");
|
||||
l::debug("Timeout: " . self::$timeout . "s; threads: " . count($this->threads));
|
||||
l::debug("Using URL {$this->url}");
|
||||
|
||||
$this->mainLoop();
|
||||
|
||||
$this->shutdown();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
/** This method initialises the manager's signal handlers.
|
||||
*/
|
||||
private function initSignals() {
|
||||
pcntl_signal(SIGTERM, array($this, "terminateHandler"));
|
||||
pcntl_signal(SIGINT, array($this, "terminateHandler"));
|
||||
pcntl_signal(SIGCHLD, array($this, "threadEndHandler"));
|
||||
}
|
||||
|
||||
|
||||
/** This method handles the TERM and INT signals, which both cause
|
||||
* a clean shutdown.
|
||||
*/
|
||||
public function terminateHandler($signo) {
|
||||
if (! $this->mustEnd) {
|
||||
l::notice("Main thread terminating on SIG" . ($signo == SIGTERM ? "TERM" : "INT"));
|
||||
$this->mustEnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** This method handles SIGCHLD and takes appropriate measures if
|
||||
* it has been caused by an error.
|
||||
*/
|
||||
public function threadEndHandler($signo) {
|
||||
// Wait for the child processes and stores their IDs
|
||||
$ended = array();
|
||||
do {
|
||||
$pid = pcntl_waitpid(-1, $status, WNOHANG);
|
||||
if ($pid > 0) {
|
||||
$ended[$pid] = $status;
|
||||
}
|
||||
} while ($pid > 0);
|
||||
|
||||
foreach ($this->threads as $thread) {
|
||||
if (array_key_exists($thread->pid, $ended)) {
|
||||
$thread->ended = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->ending) {
|
||||
l::trace("Threads have ended: " . join(', ', array_keys($ended)));
|
||||
} else {
|
||||
l::notice("Some children have met an untimely end! Terminating.");
|
||||
$this->mustEnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** This method causes the proxy checked to be run in the background.
|
||||
*/
|
||||
private function backgroundProcess() {
|
||||
if ($this->debug) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fork to the background
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == -1) {
|
||||
l::crit("The open proxy detector failed to start.");
|
||||
exit(1);
|
||||
} elseif ($pid) {
|
||||
exit(0);
|
||||
}
|
||||
posix_setsid();
|
||||
}
|
||||
|
||||
|
||||
/** This method initialises the message queues: a first queue to be
|
||||
* used as a control channel and on which requests will be received,
|
||||
* and a second queue to communicate with the threads.
|
||||
*/
|
||||
private function initMessageQueues() {
|
||||
// Create the control queue's key
|
||||
$ctrlKey = ftok(config::$main['scriptdir'] . "/lib/pcheck_manager.inc", "C");
|
||||
if ($ctrlKey == -1) {
|
||||
l::crit("Could not create the control queue's key");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the thread queue's key
|
||||
$thrdKey = ftok(config::$main['scriptdir'] . "/lib/pcheck_manager.inc", "T");
|
||||
if ($ctrlKey == -1) {
|
||||
l::crit("Could not create the thread queue's key");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the control queue
|
||||
$ctrlQueue = msg_get_queue($ctrlKey, 0666 | IPC_CREAT);
|
||||
if ($ctrlQueue === FALSE) {
|
||||
l::crit("Could not create the control queue (using key $ctrlKey)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the thread queue
|
||||
$thrdQueue = msg_get_queue($thrdKey, 0600 | IPC_CREAT);
|
||||
if ($thrdQueue === FALSE) {
|
||||
l::crit("Could not create the thread queue (using key $thrdKey)");
|
||||
@msg_remove_queue($ctrlQueue);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$this->control = $ctrlQueue;
|
||||
$this->threadQueue = $thrdQueue;
|
||||
}
|
||||
|
||||
|
||||
/** This method destroys the queues.
|
||||
*/
|
||||
private function destroyMsgQueues() {
|
||||
@msg_remove_queue($this->control);
|
||||
@msg_remove_queue($this->threadQueue);
|
||||
}
|
||||
|
||||
|
||||
/** This method initialises the data used by the proxy detector
|
||||
* threads.
|
||||
*/
|
||||
private function initData() {
|
||||
$serv = config::getParam('pcheck_server');
|
||||
$this->url = "http://$serv" . config::getParam('pcheck_path');
|
||||
$timeout = (int) config::getParam('pcheck_timeout');
|
||||
|
||||
self::$requests = array(
|
||||
"GET" => "GET {$this->url}?k=__key__ HTTP/1.0\r\n"
|
||||
. "Host: $serv\r\n"
|
||||
. "Cache-Control: no-cache\r\n"
|
||||
. "Pragma: no-cache\r\n"
|
||||
. "User-Agent: OpenCheck 1.0\r\n"
|
||||
. "\r\n",
|
||||
"POST" => "POST {$this->url} HTTP/1.0\r\n"
|
||||
. "Host: $serv\r\n"
|
||||
. "Cache-Control: no-cache\r\n"
|
||||
. "Pragma: no-cache\r\n"
|
||||
. "User-Agent: OpenCheck 1.0\r\n"
|
||||
. "Content-Length: 34\r\n"
|
||||
. "\r\n"
|
||||
. "k=__key__\r\n"
|
||||
);
|
||||
self::$timeout = $timeout;
|
||||
}
|
||||
|
||||
|
||||
/** This method initialises all threads.
|
||||
*/
|
||||
private function initThreads() {
|
||||
$nThreads = (int) config::getParam('pcheck_threads');
|
||||
for ($i = 0; $i < $nThreads; $i ++) {
|
||||
try {
|
||||
$thread = new pcheck_thread($this->threadQueue);
|
||||
} catch (Exception $e) {
|
||||
l::crit("Thread " . ($i + 1) . " failed to initialise, exiting!");
|
||||
$this->shutdown();
|
||||
exit(1);
|
||||
}
|
||||
array_push($this->threads, $thread);
|
||||
}
|
||||
$this->nFree = $nThreads;
|
||||
}
|
||||
|
||||
/** This method shuts down the manager.
|
||||
*/
|
||||
private function shutdown() {
|
||||
$this->ending = true;
|
||||
|
||||
// Kill threads
|
||||
foreach ($this->threads as $thread) {
|
||||
$thread->send(array("type" => "QUIT"));
|
||||
}
|
||||
|
||||
// Wait until all threads have ended
|
||||
do {
|
||||
$endOk = true;
|
||||
foreach ($this->threads as $thread) {
|
||||
if (! $thread->ended) {
|
||||
$endOk = false;
|
||||
sleep(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!$endOk);
|
||||
|
||||
// Destroy message queues
|
||||
$this->destroyMsgQueues();
|
||||
}
|
||||
|
||||
|
||||
/** This method contains the manager's main loop, which handles everything
|
||||
* from receiving requests and sending results to managing the detection
|
||||
* threads.
|
||||
*/
|
||||
private function mainLoop() {
|
||||
$this->requests = array();
|
||||
$this->reqHostsFound = array();
|
||||
$this->jobsQueue = array();
|
||||
$this->jobsData = array();
|
||||
|
||||
$ticker = 0;
|
||||
while (!$this->mustEnd) {
|
||||
// Check for incoming requests
|
||||
$success = msg_receive($this->control, 1, $type, 32768,
|
||||
$message, true, MSG_IPC_NOWAIT, $error);
|
||||
if (!$success && $error != MSG_ENOMSG) {
|
||||
l::error("Manager failed to receive from control queue");
|
||||
break;
|
||||
} elseif ($success) {
|
||||
$this->requestReceived(array_shift($message), $message);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for incoming results from the detection threads
|
||||
$success = msg_receive($this->threadQueue, 1, $type, 32768,
|
||||
$message, true, MSG_IPC_NOWAIT, $error);
|
||||
if (!$success && $error != MSG_ENOMSG) {
|
||||
l::error("Manager failed to receive from thread queue");
|
||||
break;
|
||||
} elseif ($success) {
|
||||
// A result has been received
|
||||
$this->resultReceived(array_shift($message), $message);
|
||||
continue;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
$ticker ++;
|
||||
|
||||
// For each request in progress, send a message every 10 ticks
|
||||
// to signal the process we're not dead yet
|
||||
if ($ticker % 10 == 0 && count($this->requests)) {
|
||||
$this->sendPing();
|
||||
}
|
||||
|
||||
// Send PID to controller every 20 ticks
|
||||
if ($ticker == 20) {
|
||||
$ticker = 0;
|
||||
self::sendToControl("PCPID {$this->pid}");
|
||||
$this->flushCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** This method handles the reception of a new request.
|
||||
*/
|
||||
private function requestReceived($fromPID, $hosts) {
|
||||
l::debug("Request received from $fromPID");
|
||||
|
||||
$now = time();
|
||||
$this->requests[$fromPID] = array();
|
||||
$this->reqHostsFound[$fromPID] = 0;
|
||||
foreach ($hosts as $host) {
|
||||
if (is_array($this->cache[$host]) && $now - $this->cache[$host]['last'] < 86400) {
|
||||
// Cached entry found, store result
|
||||
$this->requests[$fromPID][$host] = $this->cache[$host]['status'];
|
||||
$this->reqHostsFound[$fromPID] ++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// No cached entry found
|
||||
$this->requests[$fromPID][$host] = -2;
|
||||
if (is_array($this->jobsData[$host])) {
|
||||
// We're already trying to detect this host
|
||||
continue;
|
||||
}
|
||||
|
||||
// This host needs to be detected
|
||||
$this->addToJobsQueue($host);
|
||||
}
|
||||
|
||||
if ($this->reqHostsFound[$fromPID] == count($this->requests[$fromPID])) {
|
||||
// The request could be satisfied directly from cached data
|
||||
$this->sendResponse($fromPID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** This method stores the results of a scan performed by one of the
|
||||
* detection threads.
|
||||
*/
|
||||
private function resultReceived($fromThread, $result) {
|
||||
list($host, $found) = $result;
|
||||
|
||||
// If a proxy was detected, log it
|
||||
if ($found) {
|
||||
l::info("Found open proxy at $host on port $port");
|
||||
}
|
||||
|
||||
// Store the results
|
||||
$this->jobsData[$host][1] |= $found;
|
||||
$this->jobsData[$host][0] --;
|
||||
if ($this->jobsData[$host][0] == 0) {
|
||||
$this->hostFinished($host);
|
||||
}
|
||||
|
||||
// Increase amount of free threads, set the thread as free
|
||||
$this->nFree ++;
|
||||
foreach ($this->threads as $thread) {
|
||||
if ($thread->pid == $fromThread) {
|
||||
$thread->free = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Shift the jobs queue
|
||||
$this->moveQueue();
|
||||
}
|
||||
|
||||
|
||||
/** This method adds the jobs required to scan a host to the queue.
|
||||
*/
|
||||
private function addToJobsQueue($host) {
|
||||
l::trace("Adding host $host to the queue...");
|
||||
|
||||
$this->jobsData[$host] = array(count(self::$ports), false);
|
||||
foreach (self::$ports as $port) {
|
||||
array_push($this->jobsQueue, array($host, $port));
|
||||
}
|
||||
|
||||
$this->moveQueue();
|
||||
}
|
||||
|
||||
|
||||
/** This method returns the response to a request through the queue.
|
||||
*/
|
||||
private function sendResponse($requestPID) {
|
||||
$request = $this->requests[$requestPID];
|
||||
|
||||
$nRequests = array();
|
||||
$nReqHF = array();
|
||||
foreach ($this->requests as $id => $data) {
|
||||
if ($id != $requestPID) {
|
||||
$nRequests[$id] = $data;
|
||||
$nReqHF[$id] = $this->reqHostsFound[$id];
|
||||
}
|
||||
}
|
||||
$this->reqHostsFound = $nReqHF;
|
||||
$this->requests = $nRequests;
|
||||
|
||||
l::debug("Sending response to process #$requestPID");
|
||||
msg_send($this->control, $requestPID, $request, true);
|
||||
}
|
||||
|
||||
|
||||
/** This method sends a "ping" packet to all waiting processes.
|
||||
*/
|
||||
private function sendPing() {
|
||||
l::trace("Pinging processes");
|
||||
foreach (array_keys($this->requests) as $id) {
|
||||
msg_send($this->control, $id, "PING", true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** This method is called when the processing of a host
|
||||
* is complete.
|
||||
*/
|
||||
private function hostFinished($host) {
|
||||
l::trace("Host scanning finished for $host");
|
||||
$result = $this->jobsData[$host][1];
|
||||
|
||||
// Remove the entry from jobsData
|
||||
$nData = array();
|
||||
foreach ($this->jobsData as $h => $d) {
|
||||
if ($h != $host) {
|
||||
$nData[$h] = $d;
|
||||
}
|
||||
}
|
||||
$this->jobsData = $nData;
|
||||
|
||||
// Store result in cache
|
||||
$this->storeCache($host, $result);
|
||||
|
||||
// Check all requests that contained this host
|
||||
$checkRequests = array();
|
||||
foreach (array_keys($this->requests) as $request) {
|
||||
if (array_key_exists($host, $this->requests[$request])) {
|
||||
$this->reqHostsFound[$request] ++;
|
||||
$this->requests[$request][$host] = $result ? 1 : 0;
|
||||
array_push($checkRequests, $request);
|
||||
}
|
||||
}
|
||||
|
||||
// For each request that contained the host, check if it's completed
|
||||
$finished = array();
|
||||
foreach ($checkRequests as $request) {
|
||||
if ($this->reqHostsFound[$request] == count($this->requests[$request])) {
|
||||
array_push($finished, $request);
|
||||
}
|
||||
}
|
||||
|
||||
// Send responses to completed requests
|
||||
foreach ($finished as $request) {
|
||||
$this->sendResponse($request);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** This method sends free threads a scanning order if the
|
||||
* jobs queue isn't empty.
|
||||
*/
|
||||
private function moveQueue() {
|
||||
while ($this->nFree > 0 && count($this->jobsQueue)) {
|
||||
$job = array_shift($this->jobsQueue);
|
||||
foreach ($this->threads as $thread) {
|
||||
if ($thread->free) {
|
||||
l::trace("Assigning port {$job[1]} at {$job[0]} to thread {$thread->pid}");
|
||||
$this->nFree --;
|
||||
$thread->free = false;
|
||||
$thread->send(array(
|
||||
"type" => "SCAN",
|
||||
"scan" => $job
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** This method stores the result of a scan in the cache.
|
||||
*/
|
||||
private function storeCache($host, $result) {
|
||||
$this->cache[$host] = array(
|
||||
"status" => $result ? 1 : 0,
|
||||
"last" => time()
|
||||
);
|
||||
|
||||
$this->cacheModified = time();
|
||||
}
|
||||
|
||||
/** This method reads the cache from the database.
|
||||
*/
|
||||
private function initCache() {
|
||||
$this->cacheModified = 0;
|
||||
$this->cache = array();
|
||||
|
||||
$success = false;
|
||||
do {
|
||||
try {
|
||||
$db = db::connect();
|
||||
$db->enableExceptions();
|
||||
$db->query("LOCK TABLE proxy_detector IN ACCESS EXCLUSIVE MODE");
|
||||
$cacheRead = new db_copy("proxy_detector");
|
||||
$cacheRead->setAccessor($db);
|
||||
$cacheRead->execute();
|
||||
$db->end();
|
||||
$db->close();
|
||||
$db->disableExceptions();
|
||||
$success = true;
|
||||
} catch (Exception $e) {
|
||||
l::notice("Could not read cache from database. Will retry in 20 seconds.");
|
||||
l::info($e->getMessage());
|
||||
if (!is_null($db)) {
|
||||
l::trace("Closing database connection");
|
||||
$db->close();
|
||||
$db->disableExceptions();
|
||||
}
|
||||
sleep(20);
|
||||
}
|
||||
} while (! $success);
|
||||
|
||||
for ($i = 0; $i < $cacheRead->rows(); $i ++) {
|
||||
$row = $cacheRead->getRow($i);
|
||||
$this->cache[$row[0]] = array(
|
||||
"last" => $row[1],
|
||||
"status" => $row[2] == 't' ? 1 : 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** This method tries to store the cache's contents in the
|
||||
* database.
|
||||
*/
|
||||
private function flushCache() {
|
||||
if (! $this->cacheModified || time() - $this->cacheModified < 20) {
|
||||
return;
|
||||
}
|
||||
|
||||
l::debug("Flushing cache to database");
|
||||
$db = null;
|
||||
try {
|
||||
$db = db::connect();
|
||||
$db->enableExceptions();
|
||||
$db->query("LOCK TABLE proxy_detector IN ACCESS EXCLUSIVE MODE");
|
||||
$toWrite = $this->formatCache();
|
||||
$toWrite->setAccessor($db);
|
||||
$toWrite->execute();
|
||||
$db->end();
|
||||
$db->close();
|
||||
$db->disableExceptions();
|
||||
} catch (Exception $e) {
|
||||
l::notice("Could not write cache to database.");
|
||||
l::info($e->getMessage());
|
||||
if (!is_null($db)) {
|
||||
l::trace("Closing database connection");
|
||||
$db->close();
|
||||
$db->disableExceptions();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->cacheModified = 0;
|
||||
}
|
||||
|
||||
|
||||
/** This method prepares the cache for copy into the database.
|
||||
*/
|
||||
private function formatCache() {
|
||||
$cache = new db_copy("proxy_detector", db_copy::copyToClean);
|
||||
$now = time();
|
||||
foreach ($this->cache as $host => $data) {
|
||||
if ($now - $data['last'] > 3 * 86400) {
|
||||
continue;
|
||||
}
|
||||
$cache->appendRow(array($host, $data['last'], $data['status'] ? 't' : 'f'));
|
||||
}
|
||||
return $cache;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
|
@ -1,144 +0,0 @@
|
|||
<?php
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// LegacyWorlds Beta 5
|
||||
// Game libraries
|
||||
//
|
||||
// lib/pcheck_thread.inc
|
||||
//
|
||||
// This library contains the code of the open proxy detector's scanning
|
||||
// threads.
|
||||
//
|
||||
// Copyright(C) 2004-2008, DeepClone Development
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
|
||||
class pcheck_thread {
|
||||
|
||||
/** The process ID of the thread.
|
||||
*/
|
||||
public $pid;
|
||||
|
||||
/** The message queue the thread is bound to. Undefined in the
|
||||
* parent process.
|
||||
*/
|
||||
private $queue;
|
||||
|
||||
/** This property indicates that the thread has ended.
|
||||
*/
|
||||
public $ended = false;
|
||||
|
||||
|
||||
/** The constructor forks (throwing an exception on failure), then
|
||||
* depending on whether it is in the parent process or in the child,
|
||||
* returns or enters the instruction loop.
|
||||
*/
|
||||
public function __construct($queue) {
|
||||
$pid = @pcntl_fork();
|
||||
if ($pid == -1) {
|
||||
throw new Exception("Unable to fork");
|
||||
}
|
||||
|
||||
if ($pid != 0) {
|
||||
// In the parent, store the child's PID and get going.
|
||||
$this->pid = $pid;
|
||||
$this->free = true;
|
||||
$this->queue = $queue;
|
||||
return;
|
||||
}
|
||||
|
||||
// In the child, store our PID and the queue, then starts
|
||||
// waiting for instructions.
|
||||
$this->pid = posix_getpid();
|
||||
$this->queue = $queue;
|
||||
$this->waitLoop();
|
||||
}
|
||||
|
||||
|
||||
/** This method is called by the manager to send messages to the
|
||||
* threads.
|
||||
*/
|
||||
public function send($message) {
|
||||
return $this->ended ? false : msg_send($this->queue, $this->pid, $message, true);
|
||||
}
|
||||
|
||||
|
||||
/** This method implements the instruction loop.
|
||||
*/
|
||||
private function waitLoop() {
|
||||
$quit = false;
|
||||
$error = false;
|
||||
|
||||
do {
|
||||
$success = msg_receive($this->queue, $this->pid, $type, 32768, $message, true);
|
||||
if (! $success) {
|
||||
l::error("Child failed to receive a message");
|
||||
$quit = $error = true;
|
||||
} elseif ($message['type'] == 'QUIT') {
|
||||
$quit = true;
|
||||
} elseif ($message['type'] == 'SCAN') {
|
||||
list($host, $port) = $message['scan'];
|
||||
|
||||
$found = $this->executeCheck($host, $port, "GET")
|
||||
|| $this->executeCheck($host, $port, "POST");
|
||||
|
||||
if (!msg_send($this->queue, 1, array($this->pid, $host, $found), true)) {
|
||||
l::error("Child failed to send message");
|
||||
$quit = $error = true;
|
||||
}
|
||||
} else {
|
||||
l::notice("Unknown message {$message['type']} received");
|
||||
}
|
||||
} while (!$quit);
|
||||
|
||||
exit($error ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
/** This method will try to check one port for open proxy software, using
|
||||
* a specific method (POST or GET).
|
||||
*/
|
||||
private function executeCheck($ipAddress, $port, $method) {
|
||||
$key = md5(uniqid(rand()));
|
||||
|
||||
// Open the socket
|
||||
$socket = @fsockopen("tcp://$ipAddress", $port, $errno, $errstr, pcheck_manager::$timeout);
|
||||
if ($socket === FALSE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure I/O doesn't timeout
|
||||
stream_set_timeout($socket, pcheck_manager::$timeout);
|
||||
|
||||
// Send the request
|
||||
$result = @fwrite($socket, preg_replace('/__key__/', $key, pcheck_manager::$requests[$method]));
|
||||
if ($result !== FALSE) {
|
||||
$info = stream_get_meta_data($socket);
|
||||
if ($info['timed_out']) {
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the page
|
||||
if ($result !== FALSE) {
|
||||
$result = @fread($socket, 4096);
|
||||
}
|
||||
if ($result !== FALSE) {
|
||||
$info = stream_get_meta_data($socket);
|
||||
if ($info['timed_out']) {
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Close the socket
|
||||
@fclose($socket);
|
||||
if ($result === FALSE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return preg_match("/Key is \\<$key\\>/", $result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// LegacyWorlds Beta 5
|
||||
// Game libraries
|
||||
//
|
||||
// proxycheck.php
|
||||
//
|
||||
// This is the main script for the proxy detector.
|
||||
//
|
||||
// Copyright(C) 2004-2008, DeepClone Development
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
|
||||
/* Checks for fork() */
|
||||
if (!(function_exists('pcntl_fork') || $__runFromAdmin)) {
|
||||
die("This script may not be called from the web server.\n");
|
||||
}
|
||||
|
||||
/* Load the required libraries */
|
||||
$__loader = array(
|
||||
'log', 'classloader',
|
||||
'version', 'game', 'tick', 'config',
|
||||
'db_connection', 'db_accessor', 'db_copy',
|
||||
'pcheck_thread', 'pcheck_manager', 'pcheck'
|
||||
);
|
||||
require_once("loader.inc");
|
||||
|
||||
|
||||
l::setSyslogPrefix("lwProxy");
|
||||
|
||||
if (count($argv) > 1) {
|
||||
/* Checks for command line arguments */
|
||||
if (count($argv) > 2 && ($argv[1] == '-c' || $argv[1] == '-f')) {
|
||||
$addresses = $argv;
|
||||
array_shift($addresses);
|
||||
array_shift($addresses);
|
||||
|
||||
print "Running manual check, please wait ...\n";
|
||||
try {
|
||||
$results = pcheck::check($addresses, $argv[1] == '-f');
|
||||
} catch (Exception $e) {
|
||||
print "{$argv[0]}: " . $e->getMessage() . "\n";
|
||||
exit(1);
|
||||
}
|
||||
foreach ($results as $address => $proxy) {
|
||||
print "\t$address - ";
|
||||
switch ($proxy) {
|
||||
case -1: print "detection failed"; break;
|
||||
case 0: print "no proxy detected"; break;
|
||||
case 1: print "OPEN PROXY DETECTED!"; break;
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
||||
} elseif ($argv[1] != "-d") {
|
||||
die("Syntax: {$argv[0]}\n\t -> to run as a daemon\n\t{$argv[0]} -d\n\t -> to run in debugging mode\n\t{$argv[0]} -c ip [ip [...]]\n\t -> to check addresses for open proxies\n\t{$argv[0]} -f ip [ip [...]]\n\t -> same as -c, but doesn't check for a running server\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Starts the main thread */
|
||||
@posix_setgid(33);
|
||||
new pcheck_manager($argv[1] == "-d");
|
||||
|
||||
?>
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
class page_handler {
|
||||
|
||||
var $engines = array('xml');
|
||||
|
||||
|
||||
function xml($input) {
|
||||
$data = new data_leaf('MacWidget', config::getParam('widgetURL'));
|
||||
$data->setAttribute('latest', config::getParam('latestWidget'));
|
||||
$data->setAttribute('oldestOk', config::getParam('oldestWidget'));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
class page_handler {
|
||||
public $engines = array('page');
|
||||
public $noTracking = true;
|
||||
|
||||
public function handle($input) {
|
||||
$key = strtolower($input['k']);
|
||||
if (!$key || strlen($key) != 32 || preg_match('/[^a-z0-9]/', $key)) {
|
||||
$this->data = "X";
|
||||
} else {
|
||||
$this->data = "Key is $key";
|
||||
}
|
||||
$this->output = "pcheck";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -33,7 +33,7 @@ class page_layout {
|
|||
}
|
||||
|
||||
public function header($pg, $lg) {
|
||||
if ($pg == "ppipn" || $pg == "pcheck") {
|
||||
if ($pg == "ppipn") {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class page_layout {
|
|||
}
|
||||
|
||||
public function footer($pg, $lg) {
|
||||
if ($pg == "ppipn" || $pg == "pcheck") {
|
||||
if ($pg == "ppipn") {
|
||||
echo $this->pageContents;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ $__loader = array(
|
|||
'log', 'classloader',
|
||||
'version', 'game', 'tick', 'config',
|
||||
'db_connection', 'db_accessor', 'db_copy', 'db',
|
||||
'pcheck', 'library', 'tick_manager',
|
||||
'library', 'tick_manager',
|
||||
);
|
||||
require_once("loader.inc");
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Add table
Reference in a new issue