diff --git a/.actionScriptProperties b/.actionScriptProperties new file mode 100644 index 0000000..4569f57 --- /dev/null +++ b/.actionScriptProperties @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/.flexProperties b/.flexProperties new file mode 100644 index 0000000..adaa3ea --- /dev/null +++ b/.flexProperties @@ -0,0 +1,2 @@ + + diff --git a/.project b/.project new file mode 100644 index 0000000..821ecde --- /dev/null +++ b/.project @@ -0,0 +1,18 @@ + + + ubChattin + + + + + + com.adobe.flexbuilder.project.flexbuilder + + + + + + com.adobe.flexbuilder.project.flexnature + com.adobe.flexbuilder.project.actionscriptnature + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..ee24e63 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +#Tue Feb 05 20:47:18 EST 2008 +eclipse.preferences.version=1 +encoding/=utf-8 diff --git a/html-template/AC_OETags.js b/html-template/AC_OETags.js new file mode 100644 index 0000000..e77e6fd --- /dev/null +++ b/html-template/AC_OETags.js @@ -0,0 +1,276 @@ +// Flash Player Version Detection - Rev 1.6 +// Detect Client Browser type +// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved. +var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; +var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; +var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; + +function ControlVersion() +{ + var version; + var axo; + var e; + + // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry + + try { + // version will be set for 7.X or greater players + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + version = axo.GetVariable("$version"); + } catch (e) { + } + + if (!version) + { + try { + // version will be set for 6.X players only + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + + // installed player is some revision of 6.0 + // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29, + // so we have to be careful. + + // default to the first public version + version = "WIN 6,0,21,0"; + + // throws if AllowScripAccess does not exist (introduced in 6.0r47) + axo.AllowScriptAccess = "always"; + + // safe to call for 6.0r47 or greater + version = axo.GetVariable("$version"); + + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 4.X or 5.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = axo.GetVariable("$version"); + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 3.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = "WIN 3,0,18,0"; + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 2.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + version = "WIN 2,0,0,11"; + } catch (e) { + version = -1; + } + } + + return version; +} + +// JavaScript helper required to detect Flash Player PlugIn version information +function GetSwfVer(){ + // NS/Opera version >= 3 check for Flash plugin in plugin array + var flashVer = -1; + + if (navigator.plugins != null && navigator.plugins.length > 0) { + if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { + var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; + var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; + var descArray = flashDescription.split(" "); + var tempArrayMajor = descArray[2].split("."); + var versionMajor = tempArrayMajor[0]; + var versionMinor = tempArrayMajor[1]; + var versionRevision = descArray[3]; + if (versionRevision == "") { + versionRevision = descArray[4]; + } + if (versionRevision[0] == "d") { + versionRevision = versionRevision.substring(1); + } else if (versionRevision[0] == "r") { + versionRevision = versionRevision.substring(1); + if (versionRevision.indexOf("d") > 0) { + versionRevision = versionRevision.substring(0, versionRevision.indexOf("d")); + } + } + var flashVer = versionMajor + "." + versionMinor + "." + versionRevision; + } + } + // MSN/WebTV 2.6 supports Flash 4 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; + // WebTV 2.5 supports Flash 3 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; + // older WebTV supports Flash 2 + else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; + else if ( isIE && isWin && !isOpera ) { + flashVer = ControlVersion(); + } + return flashVer; +} + +// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available +function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) +{ + versionStr = GetSwfVer(); + if (versionStr == -1 ) { + return false; + } else if (versionStr != 0) { + if(isIE && isWin && !isOpera) { + // Given "WIN 2,0,0,11" + tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] + tempString = tempArray[1]; // "2,0,0,11" + versionArray = tempString.split(","); // ['2', '0', '0', '11'] + } else { + versionArray = versionStr.split("."); + } + var versionMajor = versionArray[0]; + var versionMinor = versionArray[1]; + var versionRevision = versionArray[2]; + + // is the major.revision >= requested major.revision AND the minor version >= requested minor + if (versionMajor > parseFloat(reqMajorVer)) { + return true; + } else if (versionMajor == parseFloat(reqMajorVer)) { + if (versionMinor > parseFloat(reqMinorVer)) + return true; + else if (versionMinor == parseFloat(reqMinorVer)) { + if (versionRevision >= parseFloat(reqRevision)) + return true; + } + } + return false; + } +} + +function AC_AddExtension(src, ext) +{ + if (src.indexOf('?') != -1) + return src.replace(/\?/, ext+'?'); + else + return src + ext; +} + +function AC_Generateobj(objAttrs, params, embedAttrs) +{ + var str = ''; + if (isIE && isWin && !isOpera) + { + str += ' '; + str += ''; + } else { + str += '= 0) ? document.location.href.substr(idx+1) : ''; + } + + /* Get the current location hash excluding the '#' symbol. */ + function setHash(hash) { + // It would be nice if we could use document.location.hash here, + // but it's faulty sometimes. + if (hash == '') hash = '#' + document.location.hash = hash; + } + + function createState(baseUrl, newUrl, flexAppUrl) { + return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null }; + } + + /* Add a history entry to the browser. + * baseUrl: the portion of the location prior to the '#' + * newUrl: the entire new URL, including '#' and following fragment + * flexAppUrl: the portion of the location following the '#' only + */ + function addHistoryEntry(baseUrl, newUrl, flexAppUrl) { + + //delete all the history entries + forwardStack = []; + + if (browser.ie) { + //Check to see if we are being asked to do a navigate for the first + //history entry, and if so ignore, because it's coming from the creation + //of the history iframe + if (flexAppUrl == defaultHash && document.location.href == initialHref && _ie_firstload) { + currentHref = initialHref; + return; + } + if ((!flexAppUrl || flexAppUrl == defaultHash) && _ie_firstload) { + newUrl = baseUrl + '#' + defaultHash; + flexAppUrl = defaultHash; + } else { + // for IE, tell the history frame to go somewhere without a '#' + // in order to get this entry into the browser history. + getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl; + } + setHash(flexAppUrl); + } else { + + //ADR + if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) { + initialState = createState(baseUrl, newUrl, flexAppUrl); + } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) { + backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl); + } + + if (browser.safari) { + // for Safari, submit a form whose action points to the desired URL + if (browser.version <= 419.3) { + var file = window.location.pathname.toString(); + file = file.substring(file.lastIndexOf("/")+1); + getFormElement().innerHTML = '
'; + //get the current elements and add them to the form + var qs = window.location.search.substring(1); + var qs_arr = qs.split("&"); + for (var i = 0; i < qs_arr.length; i++) { + var tmp = qs_arr[i].split("="); + var elem = document.createElement("input"); + elem.type = "hidden"; + elem.name = tmp[0]; + elem.value = tmp[1]; + document.forms.historyForm.appendChild(elem); + } + document.forms.historyForm.submit(); + } else { + top.location.hash = flexAppUrl; + } + // We also have to maintain the history by hand for Safari + historyHash[history.length] = flexAppUrl; + _storeStates(); + } else { + // Otherwise, write an anchor into the page and tell the browser to go there + addAnchor(flexAppUrl); + setHash(flexAppUrl); + } + } + backStack.push(createState(baseUrl, newUrl, flexAppUrl)); + } + + function _storeStates() { + if (browser.safari) { + getRememberElement().value = historyHash.join(","); + } + } + + function handleBackButton() { + //The "current" page is always at the top of the history stack. + var current = backStack.pop(); + if (!current) { return; } + var last = backStack[backStack.length - 1]; + if (!last && backStack.length == 0){ + last = initialState; + } + forwardStack.push(current); + } + + function handleForwardButton() { + //summary: private method. Do not call this directly. + + var last = forwardStack.pop(); + if (!last) { return; } + backStack.push(last); + } + + function handleArbitraryUrl() { + //delete all the history entries + forwardStack = []; + } + + /* Called periodically to poll to see if we need to detect navigation that has occurred */ + function checkForUrlChange() { + + if (browser.ie) { + if (currentHref != document.location.href && currentHref + '#' != document.location.href) { + //This occurs when the user has navigated to a specific URL + //within the app, and didn't use browser back/forward + //IE seems to have a bug where it stops updating the URL it + //shows the end-user at this point, but programatically it + //appears to be correct. Do a full app reload to get around + //this issue. + if (browser.version < 7) { + currentHref = document.location.href; + document.location.reload(); + } else { + //getHistoryFrame().src = historyFrameSourcePrefix + getHash(); + } + } + } + + if (browser.safari) { + // For Safari, we have to check to see if history.length changed. + if (currentHistoryLength >= 0 && history.length != currentHistoryLength) { + //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|")); + // If it did change, then we have to look the old state up + // in our hand-maintained array since document.location.hash + // won't have changed, then call back into BrowserManager. + currentHistoryLength = history.length; + var flexAppUrl = historyHash[currentHistoryLength]; + if (flexAppUrl == '') { + //flexAppUrl = defaultHash; + } + //ADR: to fix multiple + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + pl[i].browserURLChange(flexAppUrl); + } + } else { + getPlayer().browserURLChange(flexAppUrl); + } + _storeStates(); + } + } + if (browser.firefox) { + if (currentHref != document.location.href) { + var bsl = backStack.length; + + var urlActions = { + back: false, + forward: false, + set: false + } + + if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) { + urlActions.back = true; + // FIXME: could this ever be a forward button? + // we can't clear it because we still need to check for forwards. Ugg. + // clearInterval(this.locationTimer); + handleBackButton(); + } + + // first check to see if we could have gone forward. We always halt on + // a no-hash item. + if (forwardStack.length > 0) { + if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) { + urlActions.forward = true; + handleForwardButton(); + } + } + + // ok, that didn't work, try someplace back in the history stack + if ((bsl >= 2) && (backStack[bsl - 2])) { + if (backStack[bsl - 2].flexAppUrl == getHash()) { + urlActions.back = true; + handleBackButton(); + } + } + + if (!urlActions.back && !urlActions.forward) { + var foundInStacks = { + back: -1, + forward: -1 + } + + for (var i = 0; i < backStack.length; i++) { + if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { + arbitraryUrl = true; + foundInStacks.back = i; + } + } + for (var i = 0; i < forwardStack.length; i++) { + if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { + arbitraryUrl = true; + foundInStacks.forward = i; + } + } + handleArbitraryUrl(); + } + + // Firefox changed; do a callback into BrowserManager to tell it. + currentHref = document.location.href; + var flexAppUrl = getHash(); + if (flexAppUrl == '') { + //flexAppUrl = defaultHash; + } + //ADR: to fix multiple + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + pl[i].browserURLChange(flexAppUrl); + } + } else { + getPlayer().browserURLChange(flexAppUrl); + } + } + } + //setTimeout(checkForUrlChange, 50); + } + + /* Write an anchor into the page to legitimize it as a URL for Firefox et al. */ + function addAnchor(flexAppUrl) + { + if (document.getElementsByName(flexAppUrl).length == 0) { + getAnchorElement().innerHTML += "" + flexAppUrl + ""; + } + } + + var _initialize = function () { + if (browser.ie) + { + var scripts = document.getElementsByTagName('script'); + for (var i = 0, s; s = scripts[i]; i++) { + if (s.src.indexOf("history.js") > -1) { + var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html"); + } + } + historyFrameSourcePrefix = iframe_location + "?"; + var src = historyFrameSourcePrefix; + + var iframe = document.createElement("iframe"); + iframe.id = 'ie_historyFrame'; + iframe.name = 'ie_historyFrame'; + //iframe.src = historyFrameSourcePrefix; + setTimeout(function() { + document.body.appendChild(iframe); + }, 0); + } + + if (browser.safari) + { + var rememberDiv = document.createElement("div"); + rememberDiv.id = 'safari_rememberDiv'; + document.body.appendChild(rememberDiv); + rememberDiv.innerHTML = ''; + + var formDiv = document.createElement("div"); + formDiv.id = 'safari_formDiv'; + document.body.appendChild(formDiv); + + var reloader_content = document.createElement('div'); + reloader_content.id = 'safarireloader'; + var scripts = document.getElementsByTagName('script'); + for (var i = 0, s; s = scripts[i]; i++) { + if (s.src.indexOf("history.js") > -1) { + html = (new String(s.src)).replace(".js", ".html"); + } + } + reloader_content.innerHTML = ''; + document.body.appendChild(reloader_content); + reloader_content.style.position = 'absolute'; + reloader_content.style.left = reloader_content.style.top = '-9999px'; + iframe = reloader_content.getElementsByTagName('iframe')[0]; + + if (document.getElementById("safari_remember_field").value != "" ) { + historyHash = document.getElementById("safari_remember_field").value.split(","); + } + + } + + if (browser.firefox) + { + var anchorDiv = document.createElement("div"); + anchorDiv.id = 'firefox_anchorDiv'; + document.body.appendChild(anchorDiv); + } + + //setTimeout(checkForUrlChange, 50); + } + + return { + historyHash: historyHash, + backStack: function() { return backStack; }, + forwardStack: function() { return forwardStack }, + getPlayer: getPlayer, + initialize: function(src) { + _initialize(src); + }, + setURL: function(url) { + document.location.href = url; + }, + getURL: function() { + return document.location.href; + }, + getTitle: function() { + return document.title; + }, + setTitle: function(title) { + try { + backStack[backStack.length - 1].title = title; + } catch(e) { } + //if on safari, set the title to be the empty string. + if (browser.safari) { + if (title == "") { + try { + var tmp = window.location.href.toString(); + title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#")); + } catch(e) { + title = ""; + } + } + } + document.title = title; + }, + setDefaultURL: function(def) + { + defaultHash = def; + def = getHash(); + //trailing ? is important else an extra frame gets added to the history + //when navigating back to the first page. Alternatively could check + //in history frame navigation to compare # and ?. + if (browser.ie) + { + _ie_firstload = true; + getHistoryFrame().src = historyFrameSourcePrefix + def; + window.location.replace("#" + def); + setInterval(checkForUrlChange, 50); + } + + if (browser.safari) + { + currentHistoryLength = history.length; + if (historyHash.length == 0) { + historyHash[currentHistoryLength] = def; + var newloc = "#" + def; + window.location.replace(newloc); + } else { + //alert(historyHash[historyHash.length-1]); + } + //setHash(def); + setInterval(checkForUrlChange, 50); + } + + + if (browser.firefox || browser.opera) + { + var reg = new RegExp("#" + def + "$"); + if (window.location.toString().match(reg)) { + } else { + var newloc ="#" + def; + window.location.replace(newloc); + } + setInterval(checkForUrlChange, 50); + //setHash(def); + } + + }, + + /* Set the current browser URL; called from inside BrowserManager to propagate + * the application state out to the container. + */ + setBrowserURL: function(flexAppUrl, objectId) { + if (browser.ie && typeof objectId != "undefined") { + currentObjectId = objectId; + } + //fromIframe = fromIframe || false; + //fromFlex = fromFlex || false; + //alert("setBrowserURL: " + flexAppUrl); + //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ; + + var pos = document.location.href.indexOf('#'); + var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href; + var newUrl = baseUrl + '#' + flexAppUrl; + + if (document.location.href != newUrl && document.location.href + '#' != newUrl) { + currentHref = newUrl; + addHistoryEntry(baseUrl, newUrl, flexAppUrl); + currentHistoryLength = history.length; + } + + return false; + }, + + browserURLChange: function(flexAppUrl) { + var objectId = null; + if (browser.ie && currentObjectId != null) { + objectId = currentObjectId; + } + pendingURL = ''; + + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + try { + pl[i].browserURLChange(flexAppUrl); + } catch(e) { } + } + } else { + try { + getPlayer(objectId).browserURLChange(flexAppUrl); + } catch(e) { } + } + + currentObjectId = null; + } + + } + +})(); + +// Initialization + +// Automated unit testing and other diagnostics + +function setURL(url) +{ + document.location.href = url; +} + +function backButton() +{ + history.back(); +} + +function forwardButton() +{ + history.forward(); +} + +function goForwardOrBackInHistory(step) +{ + history.go(step); +} + +BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); }); diff --git a/html-template/history/historyFrame.html b/html-template/history/historyFrame.html new file mode 100644 index 0000000..e83255f --- /dev/null +++ b/html-template/history/historyFrame.html @@ -0,0 +1,29 @@ + + + + + + + + Hidden frame for Browser History support. + + diff --git a/html-template/index.template.html b/html-template/index.template.html new file mode 100644 index 0000000..20ee809 --- /dev/null +++ b/html-template/index.template.html @@ -0,0 +1,121 @@ + + + + + + + + + + + + +${title} + + + + + + + + + + + + + + + diff --git a/html-template/playerProductInstall.swf b/html-template/playerProductInstall.swf new file mode 100644 index 0000000..bdc3437 --- /dev/null +++ b/html-template/playerProductInstall.swf Binary files differ diff --git a/src/Login.mxml b/src/Login.mxml new file mode 100644 index 0000000..3121dfa --- /dev/null +++ b/src/Login.mxml @@ -0,0 +1,52 @@ + + + + 0) && (tvMaster.validateNick(username.text) == true)) { + loginButton.enabled = false; + tvMaster.masterObject.selChan.selectedIndex = selChan.selectedIndex; + funcs.authUser(username.text,selChan.selectedItem.channel); + } + else + Alert.show("Please enter a valid nick before continuing."); + } + ]]> + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Master.as b/src/Master.as new file mode 100644 index 0000000..97ee8d9 --- /dev/null +++ b/src/Master.as @@ -0,0 +1,599 @@ +/**************************************************************** + * Master.as, by Christopher Olsen + * Copyright 2007,2008 Christopher Olsen + * Mark Iuzzolino + * + * This is the Master class used by the TUve player + * + * $Id$ + ***************************************************************/ + +package { + import flash.events.NetStatusEvent; + import flash.events.SecurityErrorEvent; + import flash.events.TimerEvent; + import flash.filters.DropShadowFilter; + import flash.media.*; + import flash.net.NetConnection; + import flash.net.NetStream; + import flash.net.ObjectEncoding; + import flash.net.Responder; + import flash.net.SharedObject; + import flash.system.System; + import flash.utils.Timer; + + import mx.collections.ArrayCollection; + import mx.controls.Alert; + import mx.controls.Image; + import mx.controls.TextArea; + import mx.core.Application; + import mx.core.UIComponent; + import mx.events.FlexEvent; + import mx.formatters.DateFormatter; + import mx.managers.BrowserManager; + import mx.managers.IBrowserManager; + import mx.managers.PopUpManager; + + public class Master { + /* Variables */ + public var gateway:NetConnection; // AMF Gateway + public var masterObject:Object; // Parent reference + [Bindable] + public var userName:String; // User Infomation + public var tvNetwork:tuveNetwork; // Network Class + public var version:String = "2.4"; // Current Client Version + + /* Video Area */ + public var tvVidHolder:UIComponent = new UIComponent(); + public var tvSyncVid:Video; + public var tvLiveVid:Video; + private var tvOverlay:Image; + private var ds:DropShadowFilter; + + + /* Streams */ + public var tvSyncNC:NetConnection; // NetConnection For Sync Video + public var tvSyncNS:NetStream; // NetStream For Sync Video + public var tvSyncST:SoundTransform; // SoundTransform For Sync Video + public var tvLiveNC:NetConnection; // NetConnection For Live Video + public var tvLiveNS:NetStream; // NetStream For Live Video + public var tvLiveST:SoundTransform; // SoundTransform For Live Video + + + public var tvStartTime:Number; + public var tvGotMeta:Boolean = false; + + public var curSong:String = "NO SONG SET"; + + public var myTimer:Timer = new Timer(1000,10); + public var myCount:Number = 0; + + private var ncTimer:Timer = new Timer(5000,1); + private var ncCount:Number = 0; + + [Bindable] + public var userList:XMLList; + [Bindable] + public var songList:ArrayCollection; + [Bindable] + public var topicHistory:XMLList; + + public var chanExclusive:Number = 0; + + public var tvBrowser:IBrowserManager; + + public var tvCurRating:Number; + [Bindable] + public var tvRating:XMLList = + <> + + + + + + ; + + [Bindable] + public var chanList:ArrayCollection; + public var chanSpec:String; + + public var tvCurClass:Number; + [Bindable] + public var tvClass:XMLList = + <> + + + + + + + + ; + + public var currentChannel:String; + + [Bindable] + public var channels:XMLList; + + [Bindable] + private var metaData:Object = {duration:0}; + + private var imWins:Array; + + public var tvSO:SharedObject; + + public var vid:Number; + public var tvSyncFailed:Boolean = false; + public var tvTotal:Number; + + /* Pop Up Windows */ + private var tuveLW:listWindow; + public var tuveIW:infoWindow; + public var tuveFW:formatWindow; + public var fwClosable:Boolean = false; + public var login:Login; + public var tuveTW:tipsWindow; + + /* Playlist Variables */ + [Bindable] + public var tvPLIST:ArrayCollection; + + /* Initialization Routine */ + public function init(mO:Object):Boolean { + + /* Set Master Object */ + masterObject = mO; + + /* Initialize the AMF gateway */ + gateway = new NetConnection(); + gateway.connect("http://www.ubixonline.com/amfphp/gateway.php"); + + tvNetwork = new tuveNetwork(); + tvNetwork.tvMaster = this; + + + /* Set up sync stream */ + tvSyncNC = new NetConnection; + tvSyncNC.addEventListener(NetStatusEvent.NET_STATUS, tvNetStatus); + tvSyncNC.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); + tvSyncNC.client = this; + tvSyncNC.objectEncoding = ObjectEncoding.AMF3; + tvSyncNC.connect("rtmp://rtmp.UbixOnline.com/oflaDemo"); + + + topicHistory = new XMLList(); + + tvSO = SharedObject.getLocal("TUveINFO"); + + if (tvSO.data.myID == null) + tvSO.data.myID = new Date().getTime(); + + imWins = new Array(); + + myTimer.addEventListener(TimerEvent.TIMER,doCount); + + tvBrowser = BrowserManager.getInstance(); + ncTimer.addEventListener(TimerEvent.TIMER_COMPLETE,doReconnect); + + if (tvSO.data.myPLIST == null) + tvPLIST = new ArrayCollection(new Array({pName:"Video Sampler",songs:new ArrayCollection()})); + else + tvPLIST = tvSO.data.myPLIST; + + return(true); + } /* End init */ + + private function doReconnect(e:TimerEvent):void { + tvSyncNC.connect("rtmp://rtmp.ubixonline.com/oflaDemo"); + ncTimer.reset(); + } + + public function tuveGetChans():void { + gateway.call("tuve.getChans",new Responder(getChansRes,onFault),null); + } + private function getChansRes(result:Array):void { + if (result) { + chanList = new ArrayCollection(result); + } + doLogin(); + } + + private function doCount(event:TimerEvent):void { + myCount--; + + var min:Number = Math.floor((myCount/60)); + var sec:Number = (myCount%60); + var secStr:String; + + if (sec < 10) + secStr = "0" + sec.toString(); + else + secStr = sec.toString(); + + //masterObject.tvTimer.text = "(" + min.toString() + ":" + secStr + ")"; + } + + public function onMetaData(info:Object):void { + if (tvGotMeta == false) { + + if (tvStartTime > 0) + tvSyncNS.seek(tvStartTime); + + tvGotMeta = true; + } + } + + public function onBWDone():void { + //Alert.show("Called BWDONE"); + } + + public function onPlayStatus(info:Object):void { + } + + public function tvNetStatus(e:NetStatusEvent):void { + + if (e.info.code == "NetConnection.Connect.Success") { + if (e.currentTarget == tvSyncNC) { + if (tvSyncST != null) + tvSyncST = null; + + if (tvSyncNS != null) + tvSyncNS = null; + + tvSyncNS = new NetStream(tvSyncNC); + tvSyncNS.client = this; + //tvSyncVid.attachNetStream(tvSyncNS); + tvSyncNS.close(); + tvSyncST = tvSyncNS.soundTransform; + tvSyncNS.addEventListener(NetStatusEvent.NET_STATUS, tvNetStatus,false,0,true); + //masterObject.updateVolume(); + if (tvSyncFailed == true) { + masterObject.chatWindow.htmlText += "

[" + fmtdDate() + "] RTMP: Successfully Reconnected To Streaming Service.

"; + if (myCount > 0) + tvSyncNS.play(curSong,tvTotal - myCount); + tvSyncFailed = false; + } + } + else if (e.currentTarget == tvLiveNC) { + if (tvLiveST != null) + tvLiveST = null; + if (tvLiveNS != null) + tvLiveNS = null; + + tvLiveNS = new NetStream(tvLiveNC); + tvLiveNS.client = this; + tvLiveVid.attachNetStream(tvLiveNS); + tvLiveNS.close(); + tvLiveST = tvLiveNS.soundTransform; + tvLiveNS.addEventListener(NetStatusEvent.NET_STATUS, tvNetStatus,false,0,true); + } + else + Alert.show("Unknown stream"); + } + else if (e.info.code == "NetConnection.Connect.Closed") { + if (e.currentTarget == tvSyncNC) { + tvSyncFailed = true; + tvSyncNS = null; + masterObject.chatWindow.htmlText += "

[" + fmtdDate() + "] RTMP: Lost Connection To Streaming Service. Attempting To Reconnect.

"; + ncCount = 0; + ncTimer.reset(); + ncTimer.start(); + } + } + else if (e.info.code == "NetConnection.Connect.Failed") { + if (ncCount < 4) { + ncCount++; + masterObject.chatWindow.htmlText += "

[" + fmtdDate() + "] RTMP: Reconnect Failed. Attempting To Reconnect.

"; + ncTimer.reset(); + ncTimer.start(); + } + else { + if (e.currentTarget == tvSyncNC) + masterObject.chatWindow.htmlText += "

[" + fmtdDate() + "] RTMP: Unable to connect to the streaming service. You will not be able to watch videos.

"; + else if (e.currentTarget == tvLiveNC) + masterObject.chatWindow.htmlText += "

[" + fmtdDate() + "] RTMP: Unable to connect to the live streaming service. You will not be able to watch live video.

"; + } + } + } + + private function securityErrorHandler(event:SecurityErrorEvent):void { + Alert.show("securityError: " + event.text); + } + + /* AMF Fault Handlers */ + public function onFault(fault:String):void { + Alert.show("Error: " + fault.toString()); + } + + public function changeChannel(newChan:String):void { + tvNetwork.sendData("PART " + currentChannel + "\n"); + currentChannel = newChan; + userList = null; + userList = new XMLList(); + tvNetwork.sendData("JOIN " + currentChannel + "\n"); + } + + public function validateNick(str:String):Boolean { + var pattern:RegExp = /^[a-zA-Z0-9]*$/; + var result:Object = pattern.exec(str); + if(result == null) { + return false; + } + return true; + } + + public function parseCommand(command:String):void { + var dataArray:Array = command.split(" "); + var tmpString:String; + var i:Number; + + switch (dataArray[0]) { + case "/topic": + tmpString = dataArray[1]; + for (i=2;dataArray[i] != null;i++) + tmpString += " " + dataArray[i]; + + tvNetwork.sendData("TOPIC " + currentChannel + ":" + tmpString); + break; + case "/nick": + if (dataArray[1].length < 32) { + if (validateNick(dataArray[1]) == true) + tvNetwork.sendData("NICK " + dataArray[1]); + } + break; + case "/kick": + tmpString = dataArray[2]; + for (i=3;dataArray[i] != null;i++) + tmpString += " " + dataArray[i]; + tvNetwork.sendData("KICK " + currentChannel + ":" + dataArray[1] + ":" + tmpString + "\n"); + break; + case "/me": + case "/em": + tmpString = dataArray[1]; + for (i=2;dataArray[i] != null;i++) + tmpString += " " + dataArray[i]; + tvNetwork.sendData("EMOTE " + currentChannel + ":" + tmpString + "\n"); + masterObject.chatWindow.htmlText += "[" + fmtdDate() + "] " + userName + " " + tmpString + "\n"; + break; + case "/join": + tmpString = dataArray[1]; + if (tmpString.indexOf("#") == 0) { + changeChannel(tmpString); + } + else { + masterObject.chatWindow.htmlText += "Invalid Channel: " + tmpString + "\n"; + } + break; + case "/status": + tvNetwork.sendData("STATUS\n"); + break; + case "/whois": + if (dataArray[1] != null) + tvNetwork.sendData("WHOIS " + dataArray[1] + "\n"); + break; + case "/ban": + if (dataArray[1] != null) + if (dataArray[2] != null) + tvNetwork.sendData("BAN " + currentChannel + ":" + dataArray[1] + ":" + dataArray[2] + "\n"); + else + tvNetwork.sendData("BAN " + currentChannel + ":" + dataArray[1] + ":300\n"); + break; + case "/unban": + if (dataArray[1] != null) + tvNetwork.sendData("UNBAN " + currentChannel + ":" + dataArray[1] + "\n"); + break; + case "/list": + tvNetwork.sendData("LIST\n"); + break; + case "/s": + case "/search": + tmpString = dataArray[1]; + for (i=2;dataArray[i] != null;i++) + tmpString += " " + dataArray[i]; + masterObject.searchBox.text = tmpString; + masterObject.findSong(); + break; + case "/msg": + tmpString = dataArray[2]; + for (i=3;dataArray[i] != null;i++) + tmpString += " " + dataArray[i]; + tvNetwork.sendData("MSG " + dataArray[1] + ":" + tmpString + "\n"); + var tmpIM:imWindow; + tmpIM = findIM(dataArray[1]); + tmpIM.msgText.htmlText += "[" + fmtdDate() + "] " + userName + ": " + tmpString; + break; + case "/clear": + masterObject.chatWindow.text = ""; + break; + case "/tips": + tuveShowTW(); + break; + default: + //Alert.show("Command: " + dataArray[0]); + break; + } + } + + /* This function opens up a channel list window */ + public function tuveShowLW():void { + if (tuveLW == null) { + tuveLW = new listWindow(); + tuveLW.tvMaster = this; + tuveLW.x = ((masterObject.width - tuveLW.width) / 2); + tuveLW.y = ((masterObject.height - tuveLW.height) /2 ); + tuveLW.addEventListener("closeWindow",tuveCloseLW,false,0,true); + masterObject.addChild(tuveLW); + } + } /* End tuveShowLW() */ + + /* This function closes the channel list window */ + public function tuveCloseLW(event:FlexEvent):void { + if (tuveLW != null) { + masterObject.removeChild(tuveLW); + tuveLW = null; + } + } /* End tuveCloseLW */ + + public function tuveCloseFW(event:FlexEvent):void { + if (tuveFW != null) { + if (fwClosable == true) { + masterObject.removeChild(tuveFW); + tuveFW = null; + } + } + } + + public function tuveShowIW(vid:Number):void { + if (tuveIW == null) { + tuveIW = new infoWindow(); + tuveIW.tvSizable = false; + tuveIW.tvMaster = this; + + + tuveIW.x = ((masterObject.width - tuveIW.width) / 2); + tuveIW.y = ((masterObject.height - tuveIW.height) /2 ); + tuveIW.addEventListener("closeWindow",tuveCloseIW,false,0,true); + masterObject.addChild(tuveIW); + tuveIW.getInfo(vid); + } + else { + tuveIW.getInfo(vid); + } + } /* End invShow */ + public function tuveCloseIW(event:FlexEvent):void { + if (tuveIW != null) { + masterObject.removeChild(tuveIW); + tuveIW = null; + } + } + + public function tuveShowTW():void { + if (tuveTW == null) { + tuveTW = new tipsWindow(); + tuveTW.tvSizable = false; + tuveTW.tvMaster = this; + + + tuveTW.x = ((masterObject.width - tuveTW.width) / 2); + tuveTW.y = ((masterObject.height - tuveTW.height) /2 ); + tuveTW.addEventListener("closeWindow",tuveCloseTW,false,0,true); + masterObject.addChild(tuveTW); + } + } /* End invShow */ + public function tuveCloseTW(event:FlexEvent):void { + if (tuveTW != null) { + masterObject.removeChild(tuveTW); + tuveTW = null; + } + } + + public function setClip(tW:TextArea):void { + System.setClipboard(tW.text.substring(tW.selectionBeginIndex,tW.selectionEndIndex)); + } + + /* + * + * Private Message Functions + * + */ + public function sendIM(toNick:String,msg:String):void { + var tmpIM:imWindow; + tmpIM = findIM(toNick); + tmpIM.msgText.htmlText += "[" + fmtdDate() + "] " + toNick + ": " + msg; + } + + public function findIM(toNick:String):imWindow { + var i:Number; + var tmpIM:imWindow; + + /* Check to see if we have an open IM already */ + for (i=0;i + + + + + + + + + + \ No newline at end of file diff --git a/src/imWindow.mxml b/src/imWindow.mxml new file mode 100644 index 0000000..378bb68 --- /dev/null +++ b/src/imWindow.mxml @@ -0,0 +1,27 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/infoWindow.mxml b/src/infoWindow.mxml new file mode 100644 index 0000000..79c823c --- /dev/null +++ b/src/infoWindow.mxml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/listWindow.mxml b/src/listWindow.mxml new file mode 100644 index 0000000..2dd15f5 --- /dev/null +++ b/src/listWindow.mxml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/tipsWindow.mxml b/src/tipsWindow.mxml new file mode 100644 index 0000000..1ce7906 --- /dev/null +++ b/src/tipsWindow.mxml @@ -0,0 +1,70 @@ + + + + = 0) { + tvMaster.tvSO.data.quickTipsCur = curTip; + } + else { + curTip = tips.length - 1; + tvMaster.tvSO.data.quickTipsCur = curTip; + } + cTip.text = "Tip " + (curTip + 1) + ": " + tips[curTip]; + } + + + private function doClick():void { + if (dns.selected == true) + tvMaster.tvSO.data.quickTips = "1"; + else + tvMaster.tvSO.data.quickTips = "0"; + } + ]]> + + + + + + \ No newline at end of file diff --git a/src/tuveNetwork.as b/src/tuveNetwork.as new file mode 100644 index 0000000..718c85f --- /dev/null +++ b/src/tuveNetwork.as @@ -0,0 +1,397 @@ +/************************************************************************ + * tuveNetwork Class, by Christopher Olsen * + * Copyright 2007 Christopher Olsen * + * * + * $Id$ * + ************************************************************************/ + +package { + import flash.events.Event; + import flash.events.IOErrorEvent; + import flash.events.ProgressEvent; + import flash.events.TimerEvent; + import flash.net.Socket; + import flash.utils.Timer; + import mx.controls.Alert; + + public class tuveNetwork { + private var tvSocket:Socket; + public var tvMaster:Master; + private var attempts:Number = 0; + private var myTimer:Timer = new Timer(20000,1); + public var tvNetCon:Boolean = false; + private var curTime:Number; + + public function init():void { + myTimer.addEventListener(TimerEvent.TIMER_COMPLETE,conSocketEvent); + conSocketEvent(null); + } /* End init() */ + + private function conSocketEvent(event:TimerEvent):void { + if (attempts >=3) { + Alert.show("Cannot reconnect to server. Some services will not be available."); + } + else { + if (tvSocket == null) + this.tvSocket = new Socket(); + this.tvSocket.addEventListener(IOErrorEvent.IO_ERROR,onConnectError,false,0,true); + this.tvSocket.addEventListener(ProgressEvent.SOCKET_DATA,gotData,false,0,true); + this.tvSocket.addEventListener(Event.CONNECT,doNetAuth,false,0,true); + this.tvSocket.addEventListener(Event.CLOSE,doReconnect,false,0,true); + tvSocket.connect("Ivorytower.UbixOnline.com",9999); + attempts++; + } + } + + /* Send data to the socket */ + public function sendData(data:String):void { + tvSocket.writeUTFBytes(data); + tvSocket.flush(); + } /* End sendData */ + + /* Let's auth to the network */ + private function doNetAuth(event:Event):void { + tvNetCon = true; + tvSocket.writeUTFBytes("CLIENT " + tvMaster.version + "\n"); + tvSocket.flush(); + } /* End doNetAuth */ + + private function doNetSuccess():void { + tvMaster.userList = null; + tvMaster.userList = new XMLList(); + tvMaster.masterObject.userDispList.dataProvider = tvMaster.userList; + + tvSocket.writeUTFBytes("join " + tvMaster.currentChannel + "\n"); + tvSocket.flush(); + attempts = 0; + + tvMaster.masterObject.chatWindow.htmlText += "

[" + tvMaster.fmtdDate() + "] TUveD: Connected to server.

"; + + } + + private function onConnectError(event:IOErrorEvent):void { + if (event.text == "close") + myTimer.start(); + else + Alert.show("ERROR: " + event.text); + } /* End onConnectionError */ + + private function gotData(event:ProgressEvent):void { + var _data:String; + var _dataArray:Array; + var data:String; + var dataArray:Array; + var _i:Number; + var i:Number; + var x:Number; + var tmpString:String; + var fc:Boolean = false; + + event.bytesLoaded + + _data = this.tvSocket.readUTFBytes(this.tvSocket.bytesAvailable); + _dataArray = _data.split("\n"); + + for (_i = 0;_dataArray[_i] != null;_i++) { + data = _dataArray[_i]; + + if (data.length <= 0) + return; + + if (data.indexOf("MSG") == 0) { + dataArray = data.split(":"); + tmpString = dataArray[3]; + for (i=4;dataArray[i] != null;i++) + tmpString += ":" + dataArray[i]; + + if (dataArray[2] == "PRIVMSG") { + tvMaster.sendIM(dataArray[1],tmpString); + } + else { + if (dataArray[1] == "TUveD") + tvMaster.masterObject.chatWindow.htmlText += "

[" + tvMaster.fmtdDate() + "] " + dataArray[1] + ": " + tmpString + "

"; + else + tvMaster.masterObject.chatWindow.htmlText += "

[" + tvMaster.fmtdDate() + "] " + dataArray[1] + ": " + tmpString + "

"; + } + } /* End MSG */ + else if (data.indexOf("EMOTE") == 0) { + dataArray = data.split(":"); + tmpString = dataArray[3]; + for (i=4;dataArray[i] != null;i++) + tmpString += ":" + dataArray[i]; + tvMaster.masterObject.chatWindow.htmlText += "[" + tvMaster.fmtdDate() + "] " + dataArray[1] + " " + tmpString + "\n"; + } /* End EMOTE */ + else if (data.indexOf("PING") == 0) { + tvSocket.writeUTFBytes("PONG!\n"); + tvSocket.flush(); + } /* End PING */ + else if (data.indexOf("LIST") == 0) { + dataArray = data.split(":"); + tvMaster.tuveShowLW(); + + if (dataArray[1] == "Channel") { + tvMaster.channels = null; + tvMaster.channels = new XMLList(); + } + else { + tvMaster.channels += new XML(""); + } + + } /* End LIST */ + else if (data.indexOf("JOIN") == 0) { + dataArray = data.split(":"); + i = 2; + + while (dataArray[i] != null) { + if (dataArray[i].indexOf("&") == 0) + tmpString = dataArray[i].toString().substring(1,dataArray[i].toString().length); + else + tmpString = dataArray[i]; + + tvMaster.userList += new XML(""); + if (tvMaster.userName == tmpString) { + tvMaster.topicHistory = null; + tvMaster.topicHistory = new XMLList(); + tvMaster.masterObject.chatWindow.htmlText += "

[" + tvMaster.fmtdDate() + "] TUveD: You Are Now Talking In: " + dataArray[1] + "

"; + tvMaster.currentChannel = dataArray[1]; + + fc = false; + + for (x = 0;x < tvMaster.chanList.length;x++) { + if (tvMaster.currentChannel.toLowerCase() == tvMaster.chanList[x].channel.toLowerCase()) { + tvMaster.masterObject.selChan.selectedIndex = x; + fc = true; + } + } + + if (fc == false) { + tvMaster.chanList.addItem({channel:dataArray[1]}); + tvMaster.masterObject.selChan.selectedIndex = tvMaster.chanList.length - 1; + } + } + i += 2; + + } + } /* End JOIN */ + else if (data.indexOf("GETVIDEO") == 0) { + if (tvMaster.tvPLIST.getItemAt(tvMaster.masterObject.curList.selectedIndex).songs.length > 0) { + tvSocket.writeUTFBytes("VIDEO " + tvMaster.currentChannel + ":" + tvMaster.tvPLIST.getItemAt(tvMaster.masterObject.curList.selectedIndex).songs[0].vid + "\n"); + if (tvMaster.masterObject.curList.selectedIndex > 0) + tvMaster.tvPLIST.getItemAt(tvMaster.masterObject.curList.selectedIndex).songs.addItem(tvMaster.tvPLIST.getItemAt(tvMaster.masterObject.curList.selectedIndex).songs[0]); + tvMaster.tvPLIST.getItemAt(tvMaster.masterObject.curList.selectedIndex).songs.removeItemAt(0); + tvSocket.flush(); + tvMaster.tvSO.data.myPLIST = tvMaster.tvPLIST; + } + else { + tvSocket.writeUTFBytes("QUEUE EMPTY\n"); + tvSocket.flush(); + } + } /* End GETVIDEO */ + else if (data.indexOf("PAUSE") == 0) { + curTime = tvMaster.tvSyncNS.time; + tvMaster.myTimer.stop(); + tvMaster.tvSyncNS.close(); + } /* End PAUSE */ + else if (data.indexOf("RESUME") == 0) { + tvMaster.tvSyncNS.play(tvMaster.curSong,curTime); + tvMaster.myTimer.start(); + } /* End RESUME */ + else if (data.indexOf("SEEK") == 0) { + dataArray = data.split(":"); + if (dataArray[1] != null) + tvMaster.tvSyncNS.seek(Number(dataArray[1])); + } /* End SEEK */ + else if (data.indexOf("CURPOS") == 0) { + dataArray = data.split(":"); + if (dataArray[3].indexOf("stream") == 0) { + tvMaster.tvLiveNS.play(dataArray[3],-1); + tvMaster.tvLiveVid.width = 160; + tvMaster.tvLiveVid.height = 120; + tvMaster.tvLiveVid.y = 30; + tvMaster.tvLiveVid.x = 40; + } + else { + tvMaster.tvGotMeta = false; + tvMaster.curSong = dataArray[3]; + if (tvMaster.tvSyncNC.connected == false) { + tvMaster.tvSyncFailed = true; + tvMaster.masterObject.chatWindow.htmlText += "

You are not currently connected to the video streaming service. Attempting Reconnect.

"; + return; + } + tvMaster.tvSyncNS.close(); + tvMaster.myTimer.stop(); + tvMaster.myTimer.reset(); + tvMaster.tvStartTime = Number(dataArray[2]); + tvMaster.myTimer.delay = 1000; + tvMaster.tvTotal = Number(dataArray[5]) + tvMaster.myCount = tvMaster.tvTotal - tvMaster.tvStartTime; + tvMaster.myTimer.repeatCount = tvMaster.myCount; + tvMaster.myTimer.start(); + tvMaster.tvSyncNS.play(tvMaster.curSong,0); + + tvMaster.masterObject.songTitle.text = dataArray[4]; + tvMaster.tvBrowser.setTitle(dataArray[4]); + tvMaster.vid = Number(dataArray[6]); + } + } /* End CURPOS */ + else if (data.indexOf("BAN") == 0) { + if (tvMaster.tuveFW == null) { + tvMaster.tuveFW = new formatWindow(); + tvMaster.masterObject.addChild(tvMaster.tuveFW); + tvMaster.tuveFW.tvMaster = tvMaster; + tvMaster.tuveFW.addEventListener("closeWindow",tvMaster.tuveCloseFW,false,0,true); + } + } /* End BAN */ + else if (data.indexOf("KICK") == 0) { + dataArray = data.split(":"); + tmpString = dataArray[3]; + for (i=4;dataArray[i] != null;i++) + tmpString += ":" + dataArray[i]; + tvMaster.masterObject.chatWindow.htmlText += "You Have Been Kick By: " + dataArray[2] + " For " + tmpString + "\n"; + tvMaster.userList = null; + tvMaster.userList = new XMLList; + } /* End KICK */ + else if (data.indexOf("PART") == 0) { + dataArray = data.split(":"); + + for (i=0;i"); + tvMaster.masterObject.userDispList.dataProvider = tvMaster.userList; + break; + } + } + } /* End NICK */ + else if (data.indexOf("MODE") == 0) { + dataArray = data.split(":"); + return; + switch (dataArray[2]) { + case 'E': + if (dataArray[3] != '0') + tvMaster.masterObject.tvE.selected = true; + else + tvMaster.masterObject.tvE.selected = false; + tvMaster.chanExclusive = Number(dataArray[3]); + break; + case 'R': + if (dataArray[3] == '1') + tvMaster.masterObject.tvR.selected = true; + else + tvMaster.masterObject.tvR.selected = false; + break; + case 'Q': + if (dataArray[3] == '1') + tvMaster.masterObject.tvQ.selected = true; + else + tvMaster.masterObject.tvQ.selected = false; + break; + case 'T': + if (dataArray[3] == '1') + tvMaster.masterObject.tvT.selected = true; + else + tvMaster.masterObject.tvT.selected = false; + tvMaster.masterObject.tvTime.text = dataArray[4]; + break; + case 'A': + for (i = 0;i"); + tvMaster.masterObject.userDispList.dataProvider = tvMaster.userList; + break; + } + } + break; + } + } /* End MODE */ + else if (data.indexOf("IDENT") == 0) { + dataArray = data.split(":"); + if (dataArray[1] == 0) { + doNetSuccess(); + tvMaster.authSuccess(); + } + else { + tvMaster.authFail(dataArray[2]); + } + } /* End IDENT */ + else if (data.indexOf("TOPIC") == 0) { + var topic:Object = new Object(); + dataArray = data.split(":"); + tmpString = dataArray[2]; + for (i=3;dataArray[i] != null;i++) + tmpString += ":" + dataArray[i]; + + for (i=0;i"); + tvMaster.masterObject.topicNew.selectedIndex = tvMaster.topicHistory.length() - 1; + } /* End TOPIC */ + else if (data.indexOf("CLIENT") == 0) { + dataArray = data.split(":"); + if (Number(dataArray[1]) == 1) + Alert.show(dataArray[2]); + + tvSocket.writeUTFBytes("IDENT " + tvMaster.userName + ":" + tvMaster.tvSO.data.myID + "\n"); + tvSocket.flush(); + } /* End CLIENT */ + } /*End big for */ + } + + /* Reconnect when connection fails */ + private function doReconnect(event:Event):void { + tvMaster.masterObject.chatWindow.htmlText += "

DISCONNECTED From Server!!!

"; + tvNetCon = false; + myTimer.start(); /* Reconnect */ + } /* End doReconnect() */ + + } /* End podzNEtwork Class */ + + } /* End package */ \ No newline at end of file diff --git a/src/tvWindow.as b/src/tvWindow.as new file mode 100644 index 0000000..9a6c267 --- /dev/null +++ b/src/tvWindow.as @@ -0,0 +1,489 @@ +/**************************************************************** + * ucWindow Class, by Christopher Olsen + * Copyright 2007 Christopher Olsen + * + * This is the PodWindow container + * + * It handles the following: + * Window Resize + * Invokes Windows Close Event + * + * It contains the following: + * Top margin for window move + * Left margine for window move + * Minimum window size + * Max window size + * !! Note: The pod manager can override these values + * + * $Id$ + ***************************************************************/ + +package { + + import flash.events.MouseEvent; + import flash.events.Event; + import mx.controls.Button; + import mx.containers.Panel; + import mx.controls.Image; + import mx.events.FlexEvent + import flash.geom.Point; + import mx.managers.CursorManager; + import mx.managers.CursorManagerPriority; + import mx.core.Application; + import mx.containers.ApplicationControlBar; + import mx.controls.ColorPicker; + import mx.events.ColorPickerEvent; + import mx.events.DragEvent; + import mx.core.DragSource; + import mx.managers.DragManager; + + public class tvWindow extends Panel { + + /* Mouse Pointers */ + [Embed(source="assets/leftObliqueSize.gif")] + private static var leftObliqueSize:Class; + [Embed(source="assets/rightObliqueSize.gif")] + private static var rightObliqueSize:Class; + [Embed(source="assets/horizontalSize.gif")] + private static var horizontalSize:Class; + [Embed(source="assets/verticalSize.gif")] + private static var verticalSize:Class; + + /* The close button */ + private var closeButton:Button; + [Embed(source="assets/closeButtonUp.gif")] + private var closeButtonUp:Class; + [Embed(source="assets/closeButtonOver.gif")] + private var closeButtonOver:Class; + [Embed(source="assets/closeButtonDown.gif")] + private var closeButtonDown:Class; + /* The min button */ + private var minButton:Button; + [Embed(source="assets/minButtonUp.gif")] + private var minButtonUp:Class; + [Embed(source="assets/minButtonOver.gif")] + private var minButtonOver:Class; + [Embed(source="assets/minButtonDown.gif")] + private var minButtonDown:Class; + + /* The max button */ + private var maxButton:Button; + [Embed(source="assets/maxButtonUp.gif")] + private var maxButtonUp:Class; + [Embed(source="assets/maxButtonOver.gif")] + private var maxButtonOver:Class; + [Embed(source="assets/maxButtonDown.gif")] + private var maxButtonDown:Class; + [Embed(source="assets/restButtonUp.gif")] + private var restButtonUp:Class; + [Embed(source="assets/restButtonOver.gif")] + private var restButtonOver:Class; + [Embed(source="assets/restButtonDown.gif")] + private var restButtonDown:Class; + + private var mMC:Boolean = false; + + private var _pwMin:Boolean = false; + private var _stageY: Number; + private var _startY: Number; + private var _startX: Number; + private var _dragStartX: Number; + private var _dragStartY: Number; + private var oWidth:Number; + private var oHeight:Number; + //public var myPod:Podz; + public var closeable:Boolean = true; + private var resizePoint:Point = new Point(); + private var resizeType:Number = 0; + public var tvSizable:Boolean = true; + + /* Previous x,y width and height before maximized */ + private var oldX:Number = 0; + private var oldY:Number = 0; + private var oldWidth:Number = 0; + private var oldHeight:Number = 0; + private var pwButtonVisible:Boolean = false; + private var pwAttached:Boolean = false; + + + public function tvWindow() { + super(); + this.addEventListener(FlexEvent.CREATION_COMPLETE, pwInit); + this.addEventListener(MouseEvent.MOUSE_DOWN, mouseClickHandler, false); + this.addEventListener(MouseEvent.MOUSE_MOVE, oMouseMove, false); + this.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler,true); + this.setStyle("borderThicknessTop",0); + this.setStyle("borderThicknessBottom",0); + this.setStyle("borderThicknessLeft",0); + this.setStyle("borderThicknessRight",0); + this.setStyle("headerHeight",20); + this.setStyle("borderAlpha",.75); + this.setStyle("borderColor","#808080"); + } /* end Pod Window */ + + /****************************************************** + * Handlers Section + * + ******************************************************/ + private function pwMouseOver(event:MouseEvent):void { + pwShowButtons(); + } + + private function pwMouseOut(event:MouseEvent):void { + pwHideButtons(); + } + + private function pwInit(event:FlexEvent):void { + titleBar.addEventListener(MouseEvent.MOUSE_OVER, pwMouseOver,false,0,true); + titleBar.addEventListener(MouseEvent.MOUSE_OUT, pwMouseOut,false,0,true); + } + + /* + This function attaches the buttons to the PodWindow + */ + + public function pwAttachButtons():void { + var nC:Boolean = false; + + /* + if (myPod != null) + nC = myPod.podzMaster.podzManager.nC; + */ + + if ((closeButton == null) && (nC == false)) { + closeButton = new Button(); + closeButton.width=10; + closeButton.height=10; + closeButton.focusEnabled=false; + closeButton.setStyle("upSkin", closeButtonUp); + closeButton.setStyle("overSkin", closeButtonOver); + closeButton.setStyle("downSkin", closeButtonDown); + closeButton.addEventListener(MouseEvent.CLICK, closeButtonHandler); + titleBar.addChild(closeButton); + } + else if ((closeButton != null) && (closeable == false)) { + titleBar.removeChild(closeButton); + closeButton.removeEventListener(MouseEvent.CLICK,closeButtonHandler); + closeButton = null; + } + + if ((maxButton == null) && (tvSizable == true)) { + maxButton = new Button(); + maxButton.width=10; + maxButton.height=10; + maxButton.focusEnabled=false; + maxButton.setStyle("upSkin", maxButtonUp); + maxButton.setStyle("overSkin", maxButtonOver); + maxButton.setStyle("downSkin", maxButtonDown); + maxButton.addEventListener(MouseEvent.CLICK, maxButtonHandler); + titleBar.addChild(maxButton); + } + + if ((minButton == null) && (tvSizable == true)) { + minButton = new Button(); + minButton.width=10; + minButton.height=10; + minButton.focusEnabled=false; + minButton.setStyle("upSkin", minButtonUp); + minButton.setStyle("overSkin", minButtonOver); + minButton.setStyle("downSkin", minButtonDown); + minButton.addEventListener(MouseEvent.CLICK, minButtonHandler); + titleBar.addChild(minButton); + } + + pwAttached = true; + alignButtons(); + } /* end addButtons */ + + + // Event handler for mouse over moves + private function oMouseMove(event:MouseEvent):void { + var contentPoint:Point = event.currentTarget.globalToContent(new Point(event.stageX, event.stageY)); + + if (_pwMin == true) + return; + + if ((contentPoint.y > event.currentTarget.height - 40) && (contentPoint.x > event.currentTarget.width - 30)){ + CursorManager.removeCursor(CursorManager.currentCursorID); + CursorManager.setCursor(leftObliqueSize,CursorManagerPriority.MEDIUM, -6, -6); + mMC = true; + } + else if ((contentPoint.y < -15) && (contentPoint.x > event.currentTarget.width - 5)) { + CursorManager.removeCursor(CursorManager.currentCursorID); + CursorManager.setCursor(rightObliqueSize,CursorManagerPriority.MEDIUM, -6, -6); + mMC = true; + } + else if (mMC == true) { + CursorManager.removeCursor(CursorManager.currentCursorID); + mMC = false; + } + } /* End oMouseMose */ + + // Event handler to do actual resize + private function pwDoResize(event:MouseEvent):void { + var xPlus:Number = Application.application.parent.mouseX - resizePoint.x; + var yPlus:Number = Application.application.parent.mouseY - resizePoint.y; + var newY:Number; + + switch (resizeType) { + case 1: + this.width = oWidth + xPlus > 0 ? oWidth + xPlus : this.width; + this.height = oHeight + yPlus > 0 ? oHeight + yPlus : this.height; + break; + case 2: + this.width = oWidth + xPlus > 0 ? oWidth + xPlus : this.width; + + newY = _startY + event.stageY - _stageY; + if (newY >= 1) { + this.y = newY; + this.height = oHeight - yPlus > 0 ? oHeight - yPlus : this.height; + } + + break; + } + /* re-align the buttons */ + alignButtons(); + } + + // Event handler to end resize + private function pwEndResize(event:MouseEvent):void { + var xPlus:Number = Application.application.parent.mouseX - resizePoint.x; + var yPlus:Number = Application.application.parent.mouseY - resizePoint.y; + var newY:Number; + + event.stopImmediatePropagation(); + + Application.application.parent.removeEventListener(MouseEvent.MOUSE_MOVE, pwDoResize, true); + Application.application.parent.removeEventListener(MouseEvent.MOUSE_UP, pwEndResize, true); + + switch (resizeType) { + case 1: + this.width = oWidth + xPlus > 0 ? oWidth + xPlus : this.width; + this.height = oHeight + yPlus > 0 ? oHeight + yPlus : this.height; + break; + case 2: + this.width = oWidth + xPlus > 0 ? oWidth + xPlus : this.width; + + newY = _startY + event.stageY - _stageY; + if (newY >= 1) { + this.y = newY; + this.height = oHeight - yPlus > 0 ? oHeight - yPlus : this.height; + } + + break; + } + /* re-align the buttons */ + alignButtons(); + + /* Unset resizeType incase event is still in propagation */ + resizeType = 0; + + } /* End pwEndResize */ + + private function mouseOutHandler(event:MouseEvent):void { + CursorManager.removeCursor(CursorManager.currentCursorID); + } + + // Event handler for mouse click + private function mouseClickHandler(event:MouseEvent):void { + var contentPoint:Point = event.currentTarget.globalToContent(new Point(event.stageX, event.stageY)); + //podParent.setChildIndex(event.currentTarget,podParent.numChildren-1); + this.parentDocument.setChildIndex(event.currentTarget,this.parentDocument.numChildren-1); + + if ((contentPoint.y > this.height - 40) && (contentPoint.x > this.width - 30) && (tvSizable == true)){ + _dragStartX = event.localX; + _dragStartY = event.localY; + + oWidth = event.currentTarget.width; + oHeight = event.currentTarget.height; + + resizePoint = event.currentTarget.localToGlobal(new Point(event.currentTarget.mouseX,event.currentTarget.mouseY)); + + resizeType = 1; + + Application.application.parent.addEventListener(MouseEvent.MOUSE_UP, pwEndResize, true); + Application.application.parent.addEventListener(MouseEvent.MOUSE_MOVE, pwDoResize, true); + } + else if ((contentPoint.y < -15) && (contentPoint.x > this.width - 5) && (tvSizable == true)) { + _dragStartX = event.localX; + _dragStartY = event.localY; + + _startY = event.currentTarget.y; + _stageY = event.stageY; + + oWidth = event.currentTarget.width + oHeight = event.currentTarget.height; + resizePoint = event.currentTarget.localToGlobal(new Point(event.currentTarget.mouseX,event.currentTarget.mouseY)); + resizeType = 2; + Application.application.parent.addEventListener(MouseEvent.MOUSE_UP, pwEndResize, true); + Application.application.parent.addEventListener(MouseEvent.MOUSE_MOVE, pwDoResize, true); + } + else if ((contentPoint.y < 0) && (contentPoint.x < (event.currentTarget.width - 5))) { + Application.application.parent.addEventListener(MouseEvent.MOUSE_UP, podEndMove, true); + Application.application.parent.addEventListener(MouseEvent.MOUSE_MOVE, podDoMove, true); + _startX = event.currentTarget.x; + _startY = event.currentTarget.y; + _dragStartX = event.stageX; + _dragStartY = event.stageY; + } + + + } /* End hMouseClick */ + + public function closeButtonHandler(event:MouseEvent):void{ + dispatchEvent(new FlexEvent("closeWindow")); + } /* end buttonCloseHandler */ + + private function minButtonHandler(event:MouseEvent):void { + this.oldHeight = this.height; + this.oldWidth = this.width; + this.oldY = this.y; + + this.height = this.titleBar.height; + + maxButton.setStyle("upSkin", restButtonUp); + maxButton.setStyle("overSkin", restButtonOver); + maxButton.setStyle("downSkin", restButtonDown); + + _pwMin = true; + + } /* End minButtonHandler() */ + + private function maxButtonHandler(event:MouseEvent):void { + if (this.oldY != 0) { + if (_pwMin != true) { + this.x = this.oldX; + this.y = this.oldY; + } + else + _pwMin = false; + + this.height = this.oldHeight; + this.width = this.oldWidth; + this.oldY = 0; + maxButton.setStyle("upSkin", maxButtonUp); + maxButton.setStyle("overSkin", maxButtonOver); + maxButton.setStyle("downSkin", maxButtonDown); + } + else { + this.oldX = this.x; + this.oldY = this.y; + this.oldHeight = this.height; + this.oldWidth = this.width; + this.width = this.parentDocument.width - 2; + this.height = this.parentDocument.height - 23; + this.y = 1; + this.x = 1; + maxButton.setStyle("upSkin", restButtonUp); + maxButton.setStyle("overSkin", restButtonOver); + maxButton.setStyle("downSkin", restButtonDown); + } + + resizeType = 0; + + this.titleBar.width = this.width; + alignButtons(); + } /* End maxButtonHandler() */ + + /****************************************************** + * Private functions to the new container class + * + *****************************************************/ + public function pwHideButtons():void { + + if (closeButton != null) + closeButton.visible = false; + + if (maxButton != null) + maxButton.visible = false; + + if (minButton != null) + minButton.visible = false; + + pwButtonVisible = false; + } + + public function pwShowButtons():void { + if (pwAttached == false) + pwAttachButtons(); + + if (closeButton != null) + closeButton.visible = true; + + if (maxButton != null) + maxButton.visible = true; + + if (minButton != null) + minButton.visible = true; + + pwButtonVisible = true; + } + + private function alignButtons():void { + var bcnt:Number = 1; + + if (closeButton != null) { + closeButton.move(titleBar.width - (bcnt * 16), (titleBar.height - 10) / 2); + bcnt++; + } + if (maxButton != null) { + maxButton.move(titleBar.width - (bcnt * 16), (titleBar.height - 10) / 2); + bcnt++; + } + if (minButton != null) { + minButton.move(titleBar.width - (bcnt * 16), (titleBar.height - 10) / 2); + bcnt++; + } + + + if (pwButtonVisible == true) + pwShowButtons(); + else + pwHideButtons(); + } + + /*************/ + private function podDoMove(event:MouseEvent):void { + var newY:Number; + var newX:Number; + event.stopImmediatePropagation(); + + newY = _startY + event.stageY - _dragStartY; + newX = _startX + event.stageX - _dragStartX; + + if (newY > 1 && newX > 1) + move(newX,newY); + else if (newY > 1 && newX < 1) + move(1,newY); + else if (newY < 1 && newX < 1) + move(1,1); + else + move(newX,1); + } /* End podDoMove */ + + // Event handler to end moving + private function podEndMove(event:MouseEvent):void { + var newY:Number; + var newX:Number; + + event.stopImmediatePropagation(); + Application.application.parent.removeEventListener(MouseEvent.MOUSE_MOVE, podDoMove, true); + Application.application.parent.removeEventListener(MouseEvent.MOUSE_UP, podEndMove, true); + + newY = _startY + event.stageY - _dragStartY; + newX = _startX + event.stageX - _dragStartX; + + if (newY > 22 && newX > 1) + move(newX,newY); + else if (newY > 1 && newX < 1) + move(1,newY); + else if (newY < 1 && newX < 1) + move(1,1); + else + move(newX,1); + } /* End podEndMove */ + /*************/ + + } /* end class */ + + } /* end package */ \ No newline at end of file diff --git a/src/ubChattin.mxml b/src/ubChattin.mxml new file mode 100644 index 0000000..fa0a55b --- /dev/null +++ b/src/ubChattin.mxml @@ -0,0 +1,129 @@ + + + http://www.ubixonline.com/images/backgrounds/blueaureole.jpg + + + 0) && (tvMaster.tvNetwork.tvNetCon == true)) { + var myPattern:RegExp = / 0) { + chatHist.push(chatText.text); + if (chatHist.length > 20) + chatHist.shift(); + + chatHistPos = chatHist.length - 1; + } + + if (chatText.text.indexOf("/") == 0) { + tvMaster.parseCommand(tmpString); + chatText.text = ""; + } + else { + tvMaster.tvNetwork.sendData("MSG " + tvMaster.currentChannel + ":" + tmpString + "\n"); + var date:Date = new Date; + chatWindow.htmlText += ("[" + tvMaster.fmtdDate() + "] " + tvMaster.userName + ": " + tmpString + "\n"); + chatText.text = ""; + } + } + } /* End sendText() */ + + private function userClick():void { + tvMaster.tvNetwork.sendData('WHOIS ' + userDispList.selectedItem.@data + '\n'); + tvMaster.findIM(userDispList.selectedItem.@data); + } + + private function doHist(event:KeyboardEvent):void { + if (event.keyCode == Keyboard.DOWN) { + if (chatHistPos != (chatHist.length - 1)) { + chatText.text = chatHist[chatHistPos++]; + chatText.dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_DOWN,true,false,0.0,103)); + } + else + chatText.text = ""; + } + else if (event.keyCode == Keyboard.UP) { + if (chatHistPos >= 0) { + chatText.text = chatHist[chatHistPos--]; + chatText.dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_DOWN,true,false,0.0,103)); + } + if (chatHistPos < 0) + chatHistPos = 0; + } + } + + private function changeChan():void { + tvMaster.tvNetwork.sendData("PART " + tvMaster.currentChannel + "\n"); + tvMaster.currentChannel = tvMaster.chanList[selChan.selectedIndex].channel; + tvMaster.tvNetwork.sendData("JOIN " + tvMaster.currentChannel + "\n"); + tvMaster.userList = null; + tvMaster.userList = new XMLList(); + } + + private function setTopic():void { + tvMaster.tvNetwork.sendData("TOPIC " + tvMaster.currentChannel + ":" + tvMaster.topicHistory[topicNew.selectedIndex].@label); + } + + + ]]> + + + + + + + + + + +