// forked from uwi's Union Ranking Manager package { import flash.utils.ByteArray; import flash.display.Sprite; import flash.text.TextField; import flash.events.Event; import flash.events.MouseEvent; import com.bit101.components.*; public class FlashTest extends Sprite { private var _tf : TextField; private var _urm : UnionRankingManager; private var _rank : Text; public function FlashTest() { _tf = new TextField(); addChild(_tf); _tf.width = 465; _tf.height = 465; var id : String = this.loaderInfo.url.match(/\/([^\/\.]*)\.swf/)[1]; _urm = new UnionRankingManager(id, 20, true, false); _urm.addEventListener(UnionRankingManager.UPDATE, onURMInit); var name : InputText = new InputText(this, 20, 20, "YourName"); var score : Label = new Label(this, 130, 20, "0"); var shake : PushButton = new PushButton(this, 200, 20, "Shake!", function(e : MouseEvent) : void { score.text = int(Math.random() * 1000000).toString(); }); shake.width = 70; var submit : PushButton = new PushButton(this, 270, 20, "Submit", function(e : MouseEvent) : void { _urm.insertScore(Number(score.text), name.text); }); submit.width = 70; var clear : PushButton = new PushButton(this, 340, 20, "Clear", function(e : MouseEvent) : void { _urm.clearHighscore(); }); clear.width = 70; _rank = new Text(this, 20, 60, "connecting..."); _rank.width = 400; _rank.height = 300; } private function onURMInit(e : Event) : void { _urm.removeEventListener(UnionRankingManager.UPDATE, onURMInit); _urm.addEventListener(UnionRankingManager.UPDATE, function(e : Event) : void { var rankText : String = ""; var hl : Array = _urm.getHighscoreList(); for each(var o : Object in hl){ var d : Date = new Date(); d.setTime(o.date); rankText += o.name + "\t" + o.score + "\t" + d + "\t" + (o.ip == _urm.getIP() ? "(you)" : "") + "\n"; } _rank.text = rankText; }); } } } import flash.events.EventDispatcher; import net.user1.reactor.*; import com.adobe.serialization.json.*; import flash.events.Event; class UnionRankingManager extends EventDispatcher { private static const ATTR_NAME : String = "RANK"; public static const UPDATE : String = RoomEvent.SYNCHRONIZE; private var _reactor : Reactor; private var _rm : RoomManager; private var _room : Room = null; private var _roomName : String; private var _limRank : uint; private var _descend : Boolean; private var _uniqueIP : Boolean; // roomName : 部屋名。IDっぽいの // limRank : ランクの上限数 // descend : スコア降順かどうか // uniqueIP : 同じIPはひとつまでしかランキングに載せられないかどうか public function UnionRankingManager(roomName : String, limRank : uint, descend : Boolean = true, uniqueIP : Boolean = false) { _reactor = new Reactor(); _reactor.addEventListener(ReactorEvent.READY, onReactorReady); _reactor.connect("tryunion.com", 9100); _limRank = limRank; _roomName = roomName; _descend = descend; _uniqueIP = uniqueIP; } // roomの作成 private function onReactorReady(e : ReactorEvent) : void { var rs : RoomSettings = new RoomSettings(); rs.dieOnEmpty = false; _rm = _reactor.getRoomManager(); _room = _rm.createRoom(_roomName, rs); _rm.addEventListener(RoomManagerEvent.CREATE_ROOM_RESULTS, onCreateRoomResults); } private function onCreateRoomResults(e : RoomManagerEvent) : void { _rm.removeEventListener(RoomManagerEvent.CREATE_ROOM_RESULTS, onCreateRoomResults); _room.join(); _room.addEventListener(RoomEvent.SYNCHRONIZE, onRoomSynchronize); _room.addEventListener(RoomEvent.UPDATE_ROOM_ATTRIBUTE, onRoomSynchronize); _room.addEventListener(RoomEvent.DELETE_ROOM_ATTRIBUTE, onRoomSynchronize); } // イベント発行 private function onRoomSynchronize(e : RoomEvent) : void { dispatchEvent(new Event(UPDATE)); } // ハイスコアリストを取得 public function getHighscoreList() : Array { if(_room == null || !_room.clientIsInRoom())return null; var val : String = _room.getAttribute(ATTR_NAME); if(val == null)return []; var jd : JSONDecoder = new JSONDecoder(val); return jd.getValue(); } // ハイスコアリストを生(JSON)で取得 public function getHighscoreJSON() : String { if(_room == null || !_room.clientIsInRoom())return null; return _room.getAttribute(ATTR_NAME); } // ハイスコアをクリア public function clearHighscore() : void { if(_room == null || !_room.clientIsInRoom())return; _room.deleteAttribute(ATTR_NAME); } // 自分自身のIP取得 public function getIP() : String { return _reactor.getClientManager().self().getIP().match(/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/)[0]; } // スコアを挿入。戻り値は順位。 public function insertScore(score : Number, name : String) : int { if(_room == null || !_room.clientIsInRoom())return -2; var hl : Array = getHighscoreList(); var rank : int = getRank(score); if(rank >= _limRank)return -1; var ip : String = getIP(); if(_uniqueIP){ for(var i : uint = 0;i < hl.length;i++){ if(hl[i].ip == ip){ if(i >= rank){ hl.splice(i, 1); } break; } } if(i >= rank)hl.splice(rank, 0, {score : score, name : name, date : new Date().time, ip : ip}); }else{ hl.splice(rank, 0, {score : score, name : name, date : new Date().time, ip : ip}); } if(hl.length > _limRank){ hl = hl.slice(0, _limRank); } setHighscore(hl); return rank; } // 部屋を出る public function leave() : void { if(_room == null || !_room.clientIsInRoom())return; _room.removeEventListener(RoomEvent.SYNCHRONIZE, onRoomSynchronize); _room.leave(); } // 部屋を消す public function remove() : void { if(_room == null || !_room.clientIsInRoom())return; _room.remove(); } // ハイスコアリストをセット private function setHighscore(highscoreList : Array) : void { if(_room == null || !_room.clientIsInRoom())return; var je : JSONEncoder = new JSONEncoder(highscoreList); _room.setAttribute(ATTR_NAME, je.getString(), true, true); } // 指定スコアのハイスコアリスト内でのランクを取得 public function getRank(score : Number) : int { var hl : Array = getHighscoreList(); if(hl.length == 0)return 0; var ind : int = binarySearch(hl, score, function(s : Number, o : Object) : int { return (s - o.score) * (_descend ? -1 : 1); }); return ind >= 0 ? (ind + 1) : (-ind - 1); } // バイナリサーチ private function binarySearch(a : Array, v : Number, comp : Function) : int { var s : uint = 0; var g : uint = a.length; if(comp(v, a[g-1]) > 0)return -g-1; var c0 : int = comp(v, a[0]); if(c0 < 0)return -1; if(c0 == 0)return 0; do{ var m : uint = (s + g) >> 1; var cm : int = comp(v, a[m]); if(cm == 0)return m; if(cm < 0){ g = m; }else{ s = m; } }while(g - s > 1); return -s - 2; } } Union Ranking Manager改良版