Author: dylan
Date: 2005-04-24 20:49:04 -0400 (Sun, 24 Apr 2005)
New Revision: 671
Added:
trunk/clients/javer/
trunk/clients/javer/TODO
trunk/clients/javer/build.xml
trunk/clients/javer/manifest.mf
trunk/clients/javer/nbproject/
trunk/clients/javer/nbproject/build-impl.xml
trunk/clients/javer/nbproject/genfiles.properties
trunk/clients/javer/nbproject/project.properties
trunk/clients/javer/nbproject/project.xml
trunk/clients/javer/src/
trunk/clients/javer/src/javer/
trunk/clients/javer/src/javer/CMod.java
trunk/clients/javer/src/javer/ChannelTab.form
trunk/clients/javer/src/javer/ChannelTab.java
trunk/clients/javer/src/javer/GameMod.java
trunk/clients/javer/src/javer/HaverClient.java
trunk/clients/javer/src/javer/JaverApplet.java
trunk/clients/javer/src/javer/JaverUI.form
trunk/clients/javer/src/javer/JaverUI.java
trunk/clients/javer/src/javer/JaverUIPanel.form
trunk/clients/javer/src/javer/JaverUIPanel.java
trunk/clients/javer/src/javer/NonblockingOutputStream.java
trunk/clients/javer/src/javer/QueryTab.java
trunk/clients/javer/src/javer/SimpleTextTab.form
trunk/clients/javer/src/javer/SimpleTextTab.java
trunk/clients/javer/src/javer/TextFormatter.java
trunk/clients/javer/src/javer/TextTab.java
trunk/clients/javer/src/javer/ThreadRendezvous.java
trunk/clients/javer/src/javer/TimedInvoker.java
trunk/clients/javer/src/javer/TimerThread.java
trunk/clients/javer/src/javer/UserQueryTab.java
trunk/clients/javer/test/
Removed:
trunk/main/server/lib/Haver/Server/Plugin/
trunk/misc/guile/
trunk/misc/javer/
Modified:
trunk/
trunk/main/server/lib/Haver/Server/Base.pm
trunk/main/server/lib/Haver/Server/Listener.pm
Log:
[EMAIL PROTECTED]: dylan | 2005-04-24 18:28:52 -0400
Moved javer from misc/ to clients/
Property changes on: trunk
___________________________________________________________________
Name: svk:merge
- 1f59643a-e6e5-0310-bc24-f7d4c744f460:/haver/local/trunk:11166
1f59643a-e6e5-0310-bc24-f7d4c744f460:/haver/local/trunk-merge-10131:11178
27e50396-46e3-0310-8b22-ae223a1f35ce:/local:212
e9404bb1-7af0-0310-a7ff-e22194cd388b:/haver/local:920
edfcd8bd-4ce7-0310-a97e-bb1efd40edf3:/local:238
+ 1f59643a-e6e5-0310-bc24-f7d4c744f460:/haver/local/trunk:11166
1f59643a-e6e5-0310-bc24-f7d4c744f460:/haver/local/trunk-merge-10131:11178
27e50396-46e3-0310-8b22-ae223a1f35ce:/local:212
e9404bb1-7af0-0310-a7ff-e22194cd388b:/haver/local:927
edfcd8bd-4ce7-0310-a97e-bb1efd40edf3:/local:238
Property changes on: trunk/clients/javer
___________________________________________________________________
Name: svn:ignore
+ build
dist
Name: svk:merge
+ 1f59643a-e6e5-0310-bc24-f7d4c744f460:/haver/local/trunk/misc/javer:16426
561eb9fb-c9d5-0310-88ef-b73186cdaa44:/trunk/misc/javer:590
Added: trunk/clients/javer/TODO
===================================================================
--- trunk/clients/javer/TODO 2005-04-12 02:39:42 UTC (rev 670)
+++ trunk/clients/javer/TODO 2005-04-25 00:49:04 UTC (rev 671)
@@ -0,0 +1,7 @@
+Major planned features:
+* Message and error format strings (including timestamps)
+* Logging and menus for standalone client
+* SSL!
+* Colors
+* /set to disable e.g. .commands, ;emotes, etc
+* Synchronous-response API for the client
Added: trunk/clients/javer/build.xml
===================================================================
--- trunk/clients/javer/build.xml 2005-04-12 02:39:42 UTC (rev 670)
+++ trunk/clients/javer/build.xml 2005-04-25 00:49:04 UTC (rev 671)
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See commented blocks below for -->
+<!-- some examples of how to customize the build. -->
+<!-- (If you delete it and reopen the project it will be recreated.) -->
+<project name="javer" default="default" basedir=".">
+ <description>Builds, tests, and runs the project javer.</description>
+ <import file="nbproject/build-impl.xml"/>
+ <!--
+
+ There exist several targets which are by default empty and which can be
+ used for execution of your tasks. These targets are usually executed
+ before and after some main targets. They are:
+
+ -pre-init: called before initialization of project
properties
+ -post-init: called after initialization of project
properties
+ -pre-compile: called before javac compilation
+ -post-compile: called after javac compilation
+ -pre-compile-single: called before javac compilation of single file
+ -post-compile-single: called after javac compilation of single file
+ -pre-compile-test: called before javac compilation of JUnit tests
+ -post-compile-test: called after javac compilation of JUnit tests
+ -pre-compile-test-single: called before javac compilation of single
JUnit test
+ -post-compile-test-single: called after javac compilation of single
JUunit test
+ -pre-jar: called before JAR building
+ -post-jar: called after JAR building
+ -post-clean: called after cleaning build products
+
+ (Targets beginning with '-' are not intended to be called on their own.)
+
+ Example of inserting an obfuscator after compilation could look like this:
+
+ <target name="-post-compile">
+ <obfuscate>
+ <fileset dir="${build.classes.dir}"/>
+ </obfuscate>
+ </target>
+
+ For list of available properties check the imported
+ nbproject/build-impl.xml file.
+
+
+ Another way to customize the build is by overriding existing main targets.
+ The targets of interest are:
+
+ -init-macrodef-javac: defines macro for javac compilation
+ -init-macrodef-junit: defines macro for junit execution
+ -init-macrodef-debug: defines macro for class debugging
+ -init-macrodef-java: defines macro for class execution
+ -do-jar-with-manifest: JAR building (if you are using a manifest)
+ -do-jar-without-manifest: JAR building (if you are not using a manifest)
+ run: execution of project
+ -javadoc-build: Javadoc generation
+ test-report: JUnit report generation
+
+ An example of overriding the target for project execution could look like
this:
+
+ <target name="run" depends="javer-impl.jar">
+ <exec dir="bin" executable="launcher.exe">
+ <arg file="${dist.jar}"/>
+ </exec>
+ </target>
+
+ Notice that the overridden target depends on the jar target and not only
on
+ the compile target as the regular run target does. Again, for a list of
available
+ properties which you can use, check the target you are overriding in the
+ nbproject/build-impl.xml file.
+
+ -->
+</project>
Property changes on: trunk/clients/javer/build.xml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/manifest.mf
===================================================================
--- trunk/clients/javer/manifest.mf 2005-04-12 02:39:42 UTC (rev 670)
+++ trunk/clients/javer/manifest.mf 2005-04-25 00:49:04 UTC (rev 671)
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+X-COMMENT: Main-Class will be added automatically by build
+
Property changes on: trunk/clients/javer/nbproject
___________________________________________________________________
Name: svn:ignore
+ private
Added: trunk/clients/javer/nbproject/build-impl.xml
===================================================================
--- trunk/clients/javer/nbproject/build-impl.xml 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/nbproject/build-impl.xml 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,475 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT ***
+*** EDIT ../build.xml INSTEAD ***
+
+For the purpose of easier reading the script
+is divided into following sections:
+
+ - initialization
+ - compilation
+ - jar
+ - execution
+ - debugging
+ - javadoc
+ - junit compilation
+ - junit execution
+ - junit debugging
+ - applet
+ - cleanup
+
+-->
+<project name="javer-impl" default="build" basedir="..">
+ <target name="default" depends="test,jar,javadoc" description="Build and
test whole project."/>
+ <!--
+ ======================
+ INITIALIZATION SECTION
+ ======================
+ -->
+ <target name="-pre-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="-init-private" depends="-pre-init">
+ <property file="nbproject/private/private.properties"/>
+ </target>
+ <target name="-init-user" depends="-pre-init,-init-private">
+ <property file="${user.properties.file}"/>
+ <!-- The two properties below are usually overridden -->
+ <!-- by the active platform. Just a fallback. -->
+ <property value="1.4" name="default.javac.source"/>
+ <property value="1.4" name="default.javac.target"/>
+ </target>
+ <target name="-init-project" depends="-pre-init,-init-private,-init-user">
+ <property file="nbproject/project.properties"/>
+ </target>
+ <target name="-do-init"
depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property">
+ <available property="manifest.available" file="${manifest.file}"/>
+ <condition property="manifest.available+main.class">
+ <and>
+ <isset property="manifest.available"/>
+ <isset property="main.class"/>
+ <not>
+ <equals trim="true" arg2="" arg1="${main.class}"/>
+ </not>
+ </and>
+ </condition>
+ <available file="${test.src.dir}" property="have.tests"/>
+ <condition property="netbeans.home+have.tests">
+ <and>
+ <isset property="netbeans.home"/>
+ <isset property="have.tests"/>
+ </and>
+ </condition>
+ <condition property="no.javadoc.preview">
+ <isfalse value="${javadoc.preview}"/>
+ </condition>
+ <property value="" name="run.jvmargs"/>
+ <property value="" name="javac.compilerargs"/>
+ <property value="${basedir}" name="work.dir"/>
+ <condition property="no.deps">
+ <and>
+ <istrue value="${no.dependencies}"/>
+ </and>
+ </condition>
+ </target>
+ <target name="-post-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="-init-check"
depends="-pre-init,-init-private,-init-user,-init-project,-do-init">
+ <fail unless="src.dir">Must set src.dir</fail>
+ <fail unless="test.src.dir">Must set test.src.dir</fail>
+ <fail unless="build.dir">Must set build.dir</fail>
+ <fail unless="dist.dir">Must set dist.dir</fail>
+ <fail unless="build.classes.dir">Must set build.classes.dir</fail>
+ <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
+ <fail unless="build.test.classes.dir">Must set
build.test.classes.dir</fail>
+ <fail unless="build.test.results.dir">Must set
build.test.results.dir</fail>
+ <fail unless="build.classes.excludes">Must set
build.classes.excludes</fail>
+ <fail unless="dist.jar">Must set dist.jar</fail>
+ </target>
+ <target name="-init-macrodef-property">
+ <macrodef name="property"
uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute name="name"/>
+ <attribute name="value"/>
+ <sequential>
+ <property value="[EMAIL PROTECTED]" name="@{name}"/>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-javac">
+ <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute name="srcdir" default="${src.dir}"/>
+ <attribute name="destdir" default="${build.classes.dir}"/>
+ <attribute name="classpath" default="${javac.classpath}"/>
+ <attribute name="debug" default="${javac.debug}"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <javac srcdir="@{srcdir}" destdir="@{destdir}"
debug="@{debug}" deprecation="${javac.deprecation}" source="${javac.source}"
target="${javac.target}" includeantruntime="false">
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <compilerarg line="${javac.compilerargs}"/>
+ <customize/>
+ </javac>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-junit">
+ <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute name="includes" default="**/*Test.java"/>
+ <sequential>
+ <junit showoutput="true" fork="true" dir="${basedir}"
failureproperty="tests.failed" errorproperty="tests.failed">
+ <batchtest todir="${build.test.results.dir}">
+ <fileset includes="@{includes}" dir="${test.src.dir}"/>
+ </batchtest>
+ <classpath>
+ <path path="${run.test.classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper to="*" from="test-sys-prop.*" type="glob"/>
+ </syspropertyset>
+ <formatter usefile="false" type="brief"/>
+ </junit>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-nbjpda">
+ <macrodef name="nbjpdastart"
uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute name="name" default="${main.class}"/>
+ <attribute name="classpath" default="${debug.classpath}"/>
+ <attribute name="stopclassname" default=""/>
+ <sequential>
+ <nbjpdastart stopclassname="@{stopclassname}" name="@{name}"
addressproperty="jpda.address" transport="dt_socket">
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ </nbjpdastart>
+ </sequential>
+ </macrodef>
+ <macrodef name="nbjpdareload"
uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute name="dir" default="${build.classes.dir}"/>
+ <sequential>
+ <nbjpdareload>
+ <fileset dir="@{dir}" includes="${fix.includes}*.class"/>
+ </nbjpdareload>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-debug">
+ <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute name="classname" default="${main.class}"/>
+ <attribute name="classpath" default="${debug.classpath}"/>
+ <attribute name="args" default="${application.args}"/>
+ <sequential>
+ <java classname="@{classname}" fork="true" dir="${work.dir}">
+ <jvmarg value="-Xdebug"/>
+ <jvmarg value="-Xnoagent"/>
+ <jvmarg value="-Djava.compiler=none"/>
+ <jvmarg
value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
+ <jvmarg line="${run.jvmargs}"/>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="run-sys-prop."/>
+ <mapper to="*" from="run-sys-prop.*" type="glob"/>
+ </syspropertyset>
+ <arg line="@{args}"/>
+ </java>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-java">
+ <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute name="classname" default="${main.class}"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <java classname="@{classname}" fork="true" dir="${work.dir}">
+ <jvmarg line="${run.jvmargs}"/>
+ <classpath>
+ <path path="${run.classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="run-sys-prop."/>
+ <mapper to="*" from="run-sys-prop.*" type="glob"/>
+ </syspropertyset>
+ <customize/>
+ </java>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-presetdef-jar">
+ <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <jar compress="${jar.compress}" jarfile="${dist.jar}">
+ <fileset xmlns="http://www.netbeans.org/ns/j2se-project/1"
dir="${build.classes.dir}"/>
+ </jar>
+ </presetdef>
+ </target>
+ <target name="init"
depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar"/>
+ <!--
+ ===================
+ COMPILATION SECTION
+ ===================
+ -->
+ <target name="deps-jar" depends="init" unless="no.deps"/>
+ <target name="-pre-pre-compile" depends="init,deps-jar">
+ <mkdir dir="${build.classes.dir}"/>
+ </target>
+ <target name="-pre-compile">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="-do-compile"
depends="init,deps-jar,-pre-pre-compile,-pre-compile">
+ <j2seproject:javac
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"/>
+ <copy todir="${build.classes.dir}">
+ <fileset excludes="${build.classes.excludes}" dir="${src.dir}"/>
+ </copy>
+ </target>
+ <target name="-post-compile">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="compile"
depends="init,deps-jar,-pre-pre-compile,-pre-compile,-do-compile,-post-compile"
description="Compile project."/>
+ <target name="-pre-compile-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="-do-compile-single" depends="init,deps-jar,-pre-pre-compile">
+ <fail unless="javac.includes">Must select some files in the IDE or set
javac.includes</fail>
+ <j2seproject:javac
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1">
+ <customize>
+ <patternset includes="${javac.includes}"/>
+ </customize>
+ </j2seproject:javac>
+ </target>
+ <target name="-post-compile-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="compile-single"
depends="init,deps-jar,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single"/>
+ <!--
+ ====================
+ JAR BUILDING SECTION
+ ====================
+ -->
+ <target name="-pre-pre-jar" depends="init">
+ <dirname file="${dist.jar}" property="dist.jar.dir"/>
+ <mkdir dir="${dist.jar.dir}"/>
+ </target>
+ <target name="-pre-jar">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="-do-jar-without-manifest"
depends="init,compile,-pre-pre-jar,-pre-jar" unless="manifest.available">
+ <j2seproject:jar
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"/>
+ </target>
+ <target name="-do-jar-with-manifest"
depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available"
unless="manifest.available+main.class">
+ <j2seproject:jar
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
manifest="${manifest.file}"/>
+ </target>
+ <target name="-do-jar-with-mainclass"
depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class">
+ <j2seproject:jar
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
manifest="${manifest.file}">
+ <manifest xmlns="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute value="${main.class}" name="Main-Class"/>
+ </manifest>
+ </j2seproject:jar>
+ </target>
+ <target name="-post-jar">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="jar"
depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-post-jar"
description="Build JAR."/>
+ <!--
+ =================
+ EXECUTION SECTION
+ =================
+ -->
+ <target name="run" depends="init,compile" description="Run a main class.">
+ <j2seproject:java
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1">
+ <customize>
+ <arg line="${application.args}"/>
+ </customize>
+ </j2seproject:java>
+ </target>
+ <target name="run-single" depends="init,compile-single">
+ <fail unless="run.class">Must select one file in the IDE or set
run.class</fail>
+ <j2seproject:java
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
classname="${run.class}"/>
+ </target>
+ <!--
+ =================
+ DEBUGGING SECTION
+ =================
+ -->
+ <target name="-debug-start-debugger" if="netbeans.home" depends="init">
+ <j2seproject:nbjpdastart
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
name="${debug.class}"/>
+ </target>
+ <target name="-debug-start-debuggee" depends="init,compile">
+ <j2seproject:debug
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"/>
+ </target>
+ <target name="debug" if="netbeans.home"
depends="init,compile,-debug-start-debugger,-debug-start-debuggee"
description="Debug project in IDE."/>
+ <target name="-debug-start-debugger-stepinto" if="netbeans.home"
depends="init">
+ <j2seproject:nbjpdastart
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
stopclassname="${main.class}"/>
+ </target>
+ <target name="debug-stepinto" if="netbeans.home"
depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee"/>
+ <target name="-debug-start-debuggee-single" if="netbeans.home"
depends="init,compile-single">
+ <fail unless="debug.class">Must select one file in the IDE or set
debug.class</fail>
+ <j2seproject:debug
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
classname="${debug.class}"/>
+ </target>
+ <target name="debug-single" if="netbeans.home"
depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single"/>
+ <target name="-pre-debug-fix" depends="init">
+ <fail unless="fix.includes">Must set fix.includes</fail>
+ <property value="${fix.includes}.java" name="javac.includes"/>
+ </target>
+ <target name="-do-debug-fix" if="netbeans.home"
depends="init,-pre-debug-fix,compile-single">
+ <j2seproject:nbjpdareload
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"/>
+ </target>
+ <target name="debug-fix" if="netbeans.home"
depends="init,-pre-debug-fix,-do-debug-fix"/>
+ <!--
+ ===============
+ JAVADOC SECTION
+ ===============
+ -->
+ <target name="-javadoc-build" depends="init">
+ <mkdir dir="${dist.javadoc.dir}"/>
+ <javadoc destdir="${dist.javadoc.dir}" source="${javac.source}"
notree="${javadoc.notree}" use="${javadoc.use}" nonavbar="${javadoc.nonavbar}"
noindex="${javadoc.noindex}" splitindex="${javadoc.splitindex}"
author="${javadoc.author}" version="${javadoc.version}"
windowtitle="${javadoc.windowtitle}" private="${javadoc.private}"
failonerror="true">
+ <classpath>
+ <path path="${javac.classpath}"/>
+ </classpath>
+ <sourcepath>
+ <pathelement location="${src.dir}"/>
+ </sourcepath>
+ <fileset dir="${src.dir}"/>
+ </javadoc>
+ </target>
+ <target name="-javadoc-browse" if="netbeans.home"
unless="no.javadoc.preview" depends="init,-javadoc-build">
+ <nbbrowse file="${dist.javadoc.dir}/index.html"/>
+ </target>
+ <target name="javadoc" depends="init,-javadoc-build,-javadoc-browse"
description="Build Javadoc."/>
+ <!--
+ =========================
+ JUNIT COMPILATION SECTION
+ =========================
+ -->
+ <target name="-pre-pre-compile-test" if="have.tests"
depends="init,compile">
+ <mkdir dir="${build.test.classes.dir}"/>
+ </target>
+ <target name="-pre-compile-test">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="-do-compile-test" if="have.tests"
depends="init,compile,-pre-pre-compile-test,-pre-compile-test">
+ <j2seproject:javac
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
classpath="${javac.test.classpath}" debug="true"
destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
+ <copy todir="${build.test.classes.dir}">
+ <fileset dir="${test.src.dir}">
+ <exclude name="**/*.java"/>
+ </fileset>
+ </copy>
+ </target>
+ <target name="-post-compile-test">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="compile-test"
depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test"/>
+ <target name="-pre-compile-test-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="-do-compile-test-single" if="have.tests"
depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single">
+ <fail unless="javac.includes">Must select some files in the IDE or set
javac.includes</fail>
+ <j2seproject:javac
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
classpath="${javac.test.classpath}" debug="true"
destdir="${build.test.classes.dir}" srcdir="${test.src.dir}">
+ <customize>
+ <patternset includes="${javac.includes}"/>
+ </customize>
+ </j2seproject:javac>
+ </target>
+ <target name="-post-compile-test-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="compile-test-single"
depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single"/>
+ <!--
+ =======================
+ JUNIT EXECUTION SECTION
+ =======================
+ -->
+ <target name="-pre-test-run" if="have.tests" depends="init">
+ <mkdir dir="${build.test.results.dir}"/>
+ </target>
+ <target name="-do-test-run" if="have.tests"
depends="init,compile-test,-pre-test-run">
+ <j2seproject:junit
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"/>
+ </target>
+ <target name="-post-test-run" if="have.tests"
depends="init,compile-test,-pre-test-run,-do-test-run">
+ <fail if="tests.failed">Some tests failed; see details above.</fail>
+ </target>
+ <target name="test-report" if="have.tests" depends="init"/>
+ <target name="-test-browse" if="netbeans.home+have.tests" depends="init"/>
+ <target name="test"
depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse"
description="Run unit tests."/>
+ <target name="-pre-test-run-single" if="have.tests" depends="init">
+ <mkdir dir="${build.test.results.dir}"/>
+ </target>
+ <target name="-do-test-run-single" if="have.tests"
depends="init,compile-test-single,-pre-test-run-single">
+ <fail unless="test.includes">Must select some files in the IDE or set
test.includes</fail>
+ <j2seproject:junit
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
includes="${test.includes}"/>
+ </target>
+ <target name="-post-test-run-single" if="have.tests"
depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single">
+ <fail if="tests.failed">Some tests failed; see details above.</fail>
+ </target>
+ <target name="test-single"
depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single"
description="Run single unit test."/>
+ <!--
+ =======================
+ JUNIT DEBUGGING SECTION
+ =======================
+ -->
+ <target name="-debug-start-debuggee-test" if="have.tests"
depends="init,compile-test">
+ <fail unless="test.class">Must select one file in the IDE or set
test.class</fail>
+ <j2seproject:debug
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
args="${test.class}" classpath="${debug.test.classpath}"
classname="junit.textui.TestRunner"/>
+ </target>
+ <target name="-debug-start-debugger-test" if="netbeans.home+have.tests"
depends="init,compile-test">
+ <j2seproject:nbjpdastart
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
classpath="${debug.test.classpath}" name="${test.class}"/>
+ </target>
+ <target name="debug-test"
depends="init,compile-test,-debug-start-debugger-test,-debug-start-debuggee-test"/>
+ <target name="-do-debug-fix-test" if="netbeans.home"
depends="init,-pre-debug-fix,compile-test-single">
+ <j2seproject:nbjpdareload
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
dir="${build.test.classes.dir}"/>
+ </target>
+ <target name="debug-fix-test" if="netbeans.home"
depends="init,-pre-debug-fix,-do-debug-fix-test"/>
+ <!--
+ =========================
+ APPLET EXECUTION SECTION
+ =========================
+ -->
+ <target name="run-applet" depends="init,compile-single">
+ <fail unless="applet.url">Must select one file in the IDE or set
applet.url</fail>
+ <j2seproject:java
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
classname="sun.applet.AppletViewer">
+ <customize>
+ <arg value="${applet.url}"/>
+ </customize>
+ </j2seproject:java>
+ </target>
+ <!--
+ =========================
+ APPLET DEBUGGING SECTION
+ =========================
+ -->
+ <target name="-debug-start-debuggee-applet" if="netbeans.home"
depends="init,compile-single">
+ <fail unless="applet.url">Must select one file in the IDE or set
applet.url</fail>
+ <j2seproject:debug
xmlns:j2seproject="http://www.netbeans.org/ns/j2se-project/1"
args=""${applet.url}"" classname="sun.applet.AppletViewer"/>
+ </target>
+ <target name="debug-applet" if="netbeans.home"
depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet"/>
+ <!--
+ ===============
+ CLEANUP SECTION
+ ===============
+ -->
+ <target name="deps-clean" depends="init" unless="no.deps"/>
+ <target name="-do-clean" depends="init">
+ <delete dir="${build.dir}"/>
+ <delete dir="${dist.dir}"/>
+ </target>
+ <target name="-post-clean">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="clean" depends="init,deps-clean,-do-clean,-post-clean"
description="Clean build products."/>
+</project>
Property changes on: trunk/clients/javer/nbproject/build-impl.xml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/nbproject/genfiles.properties
===================================================================
--- trunk/clients/javer/nbproject/genfiles.properties 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/nbproject/genfiles.properties 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,6 @@
+build.xml.data.CRC32=6ef497b2
+build.xml.script.CRC32=e8133476
+build.xml.stylesheet.CRC32=ba5d3624
+nbproject/build-impl.xml.data.CRC32=6ef497b2
+nbproject/build-impl.xml.script.CRC32=e20b63b8
+nbproject/build-impl.xml.stylesheet.CRC32=1cf0b40c
Property changes on: trunk/clients/javer/nbproject/genfiles.properties
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/nbproject/project.properties
===================================================================
--- trunk/clients/javer/nbproject/project.properties 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/nbproject/project.properties 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,54 @@
+application.args=
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+debug.classpath=\
+ ${run.classpath}
+debug.test.classpath=\
+ ${run.test.classpath}
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/javer.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+jar.compress=false
+javac.classpath=\
+
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.source=${default.javac.source}
+javac.target=${default.javac.target}
+javac.test.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}:\
+ ${libs.junit.classpath}
+javadoc.author=false
+javadoc.encoding=
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+main.class=javer.JaverUI
+manifest.file=manifest.mf
+platform.active=default_platform
+run.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project
+# (you may also define separate properties like run-sys-prop.name=value
instead of -Dname=value
+# or test-sys-prop.name=value to set system properties for unit tests):
+run.jvmargs=
+run.test.classpath=\
+ ${javac.test.classpath}:\
+ ${build.test.classes.dir}
+src.dir=src
+test.src.dir=test
Property changes on: trunk/clients/javer/nbproject/project.properties
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/nbproject/project.xml
===================================================================
--- trunk/clients/javer/nbproject/project.xml 2005-04-12 02:39:42 UTC (rev
670)
+++ trunk/clients/javer/nbproject/project.xml 2005-04-25 00:49:04 UTC (rev
671)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.java.j2seproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/j2se-project/1">
+ <name>javer</name>
+ <minimum-ant-version>1.6</minimum-ant-version>
+ </data>
+ </configuration>
+</project>
Property changes on: trunk/clients/javer/nbproject/project.xml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/CMod.java
===================================================================
--- trunk/clients/javer/src/javer/CMod.java 2005-04-12 02:39:42 UTC (rev
670)
+++ trunk/clients/javer/src/javer/CMod.java 2005-04-25 00:49:04 UTC (rev
671)
@@ -0,0 +1,177 @@
+/*
+ * CMod.java
+ *
+ * Created on January 14, 2005, 7:03 PM
+ */
+
+package javer;
+import java.util.*;
+import java.io.*;
+import java.math.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class CMod extends GameMod {
+
+ boolean conspiracyExists = false;
+ boolean polling = false;
+ String innocent = null;
+ Map pollresults = null;
+ String homechannel;
+ Object pollTimer = null;
+
+ /** Creates a new instance of CMod */
+ public CMod(String homechannel) {
+ super();
+ this.homechannel = homechannel;
+ }
+
+ protected void eventPrivateNormalMessage(String who, String arg) throws
java.io.IOException {
+ if (polling) {
+ String val = arg.toLowerCase();
+ boolean choice;
+ if (val.equals("yes"))
+ choice = true;
+ else if (val.equals("no"))
+ choice = false;
+ else {
+ sendPrivateNormalMessage(who, "Huh?");
+ super.eventPrivateNormalMessage(who, arg);
+ return;
+ }
+ if (pollresults.containsKey(who)) {
+ sendPrivateNormalMessage(who, "You cannot change your
choice.");
+ } else {
+ Boolean value = new Boolean(choice);
+ pollresults.put(who, value);
+ sendPrivateNormalMessage(who, "Noted.");
+ if (pollresults.size() == players.size()) {
+ tallyResults();
+ }
+ }
+ }
+ super.eventPrivateNormalMessage(who, arg);
+ }
+
+ protected void eventIdentAccepted() throws java.io.IOException {
+ super.eventIdentAccepted();
+ join(homechannel);
+ }
+
+ public void endGame() throws java.io.IOException {
+ polling = false;
+ if (pollTimer != null) {
+ TimedInvoker.unschedule(pollTimer);
+ }
+ pollresults = null;
+ innocent = null;
+ pollTimer = null;
+ super.endGame();
+ }
+
+ public void beginGame() throws java.io.IOException {
+ Random r = new Random();
+ conspiracyExists = r.nextBoolean();
+ if (conspiracyExists) {
+ Object[] playerarray = players.toArray();
+ innocent = (String)playerarray[r.nextInt(playerarray.length)];
+ }
+ Iterator pi = players.iterator();
+ while (pi.hasNext()) {
+ String uid = (String)pi.next();
+ if (uid.equals(innocent) || !conspiracyExists) {
+ sendPrivateNormalMessage(uid, "You are an innocent in this
game.");
+ } else {
+ sendPrivateNormalMessage(uid, "You are a conspirator, and the
innocent is " + innocent);
+ }
+ }
+ sendNormalMessage(homechannel, "A game of Conspiracy has begun! You
have 10 minutes before polling phase begins.");
+ pollTimer = TimedInvoker.invokeAfter(10 * 60 * 1000, new Runnable() {
+ public void run() {
+ try {
+ beginPolling();
+ } catch (IOException e) {
+ eventIOException(e);
+ }
+ }
+ });
+ super.beginGame();
+ }
+
+ protected void beginPolling() throws IOException {
+ if (!playing)
+ return;
+ sendNormalMessage(homechannel, "Time's up! Please /msg me with 'yes'" +
+ " if you think there is a conspiracy, or 'no' if you believe" +
+ " there is no conspiracy.");
+ pollresults = new HashMap(players.size());
+ polling = true;
+ }
+
+ protected void tallyResults() throws IOException {
+ Set winners;
+ if (conspiracyExists) {
+ boolean innocentWins;
+ innocentWins = ((Boolean)pollresults.get(innocent)).booleanValue();
+ if (innocentWins)
+ winners = Collections.singleton(innocent);
+ else {
+ winners = new HashSet(players);
+ winners.remove(innocent);
+ }
+ } else {
+ Iterator it = players.iterator();
+ winners = new HashSet();
+ while (it.hasNext()) {
+ String uid = (String)it.next();
+ Boolean result = (Boolean)pollresults.get(uid);
+ if (!result.booleanValue())
+ winners.add(uid);
+ }
+ }
+ Iterator it = players.iterator();
+ sendNormalMessage(homechannel,
+ "All polls are in. The results are as follows:");
+ /* field lengths: nick 15, poll 3, win 3 */
+ sendNormalMessage(homechannel,
+ "NICK RES WIN");
+ sendNormalMessage(homechannel,
+ "=======================");
+ while (it.hasNext()) {
+ String uid = (String)it.next();
+ String nick = (String)channelMembers.get(uid);
+ boolean won = winners.contains(uid);
+ boolean vote = ((Boolean)pollresults.get(uid)).booleanValue();
+ while(nick.length() < 15) {
+ nick = nick + " ";
+ }
+ String msg = nick;
+ if (vote)
+ msg = msg + " Y ";
+ else
+ msg = msg + " N ";
+ if (won)
+ msg = msg + " Y ";
+ else
+ msg = msg + " N ";
+ sendNormalMessage(homechannel, msg);
+ }
+ sendNormalMessage(homechannel,
+ "=======================");
+ sendNormalMessage(homechannel,
+ "Game over. Thanks for playing!");
+ endGame();
+ }
+
+ public static void main(String[] args) throws Exception {
+ CMod mod = new CMod(args[3]);
+ mod.connect(args[0], args[1], Integer.decode(args[2]).intValue());
+ }
+
+ protected void eventDebugMessage(String s) throws IOException {
+ //log("DEBUG", s);
+ super.eventDebugMessage(s);
+ }
+}
Property changes on: trunk/clients/javer/src/javer/CMod.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/ChannelTab.form
===================================================================
--- trunk/clients/javer/src/javer/ChannelTab.form 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/ChannelTab.form 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+
+ <Layout
class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JSplitPane" name="jSplitPane1">
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"
value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="Center"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout
class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"
value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
+ <JSplitPaneConstraints position="left"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout
class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JTextArea" name="chatArea">
+ <Properties>
+ <Property name="editable" type="boolean" value="false"/>
+ <Property name="lineWrap" type="boolean" value="true"/>
+ </Properties>
+ <AuxValues>
+ <AuxValue name="JavaCodeGenerator_VariableModifier"
type="java.lang.Integer" value="0"/>
+ </AuxValues>
+ </Component>
+ </SubComponents>
+ </Container>
+ <Container class="javax.swing.JScrollPane" name="jScrollPane2">
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"
value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
+ <JSplitPaneConstraints position="right"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout
class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JList" name="userList">
+ <Events>
+ <EventHandler event="mouseClicked"
listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent"
handler="userClicked"/>
+ </Events>
+ <AuxValues>
+ <AuxValue name="JavaCodeGenerator_VariableModifier"
type="java.lang.Integer" value="0"/>
+ </AuxValues>
+ </Component>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+</Form>
Added: trunk/clients/javer/src/javer/ChannelTab.java
===================================================================
--- trunk/clients/javer/src/javer/ChannelTab.java 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/ChannelTab.java 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,142 @@
+/*
+ * ChannelTab.java
+ *
+ * Created on January 5, 2005, 11:50 PM
+ */
+
+package javer;
+import java.io.*;
+import java.util.*;
+import java.awt.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class ChannelTab extends javax.swing.JPanel implements QueryTab {
+
+ JaverUIPanel panel;
+ HaverClient cli;
+ String channel;
+ Set users;
+ boolean positioned = false;
+
+ /** Creates new form ChannelTab */
+ public ChannelTab(JaverUIPanel panel, HaverClient cli, String channel) {
+ this.panel = panel;
+ this.cli = cli;
+ this.channel = channel;
+ users = new java.util.TreeSet();
+ initComponents();
+ }
+
+ public String getChannel() {
+ return channel;
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ private void initComponents() {//GEN-BEGIN:initComponents
+ jSplitPane1 = new javax.swing.JSplitPane();
+ jScrollPane1 = new javax.swing.JScrollPane();
+ chatArea = new javax.swing.JTextArea();
+ jScrollPane2 = new javax.swing.JScrollPane();
+ userList = new javax.swing.JList();
+
+ setLayout(new java.awt.BorderLayout());
+
+ chatArea.setEditable(false);
+ chatArea.setLineWrap(true);
+ jScrollPane1.setViewportView(chatArea);
+
+ jSplitPane1.setLeftComponent(jScrollPane1);
+
+ userList.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseClicked(java.awt.event.MouseEvent evt) {
+ userClicked(evt);
+ }
+ });
+
+ jScrollPane2.setViewportView(userList);
+
+ jSplitPane1.setRightComponent(jScrollPane2);
+
+ add(jSplitPane1, java.awt.BorderLayout.CENTER);
+
+ }//GEN-END:initComponents
+
+ private void userClicked(java.awt.event.MouseEvent evt)
{//GEN-FIRST:event_userClicked
+ String item = (String) userList.getSelectedValue();
+ panel.activateQuery(item);
+ }//GEN-LAST:event_userClicked
+
+ public void sendText(String s) throws java.io.IOException {
+ cli.sendNormalMessage(channel, s);
+ }
+
+ public void sendAction(String s) throws java.io.IOException {
+ cli.sendAction(channel, s);
+ }
+
+ public void putText(String s) {
+ /* XXX: this is a bit of a hack */
+ if (!positioned) {
+ jSplitPane1.setDividerLocation(0.8);
+ positioned = true;
+ }
+ chatArea.append(s + "\n");
+ chatArea.setCaretPosition(chatArea.getText().length());
+ }
+
+ public void updateUsers() {
+ userList.setListData(users.toArray());
+ }
+
+ public void setUsers(Set m) {
+ try {
+ users = (SortedSet) m;
+ } catch (ClassCastException e) {
+ users = new TreeSet(m);
+ }
+ updateUsers();
+ updateSizes();
+ }
+
+ public void addUser(String who) {
+ users.add(who);
+ updateUsers();
+ }
+
+ public void delUser(String who) {
+ users.remove(who);
+ updateUsers();
+ }
+
+ public boolean hasUser(String who) {
+ return users.contains(who);
+ }
+
+ public void updateSizes() {
+ Dimension listsize = jScrollPane2.getPreferredSize();
+ Dimension windowsize = this.getSize();
+ int dividerSize = jSplitPane1.getDividerSize();
+ int pos = windowsize.width - dividerSize - listsize.width - 10;
+ if (pos < (windowsize.width * 8) / 10) {
+ jSplitPane1.setDividerLocation(0.8);
+ return;
+ }
+ jSplitPane1.setDividerLocation(pos);
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ javax.swing.JTextArea chatArea;
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JScrollPane jScrollPane2;
+ private javax.swing.JSplitPane jSplitPane1;
+ javax.swing.JList userList;
+ // End of variables declaration//GEN-END:variables
+
+}
Property changes on: trunk/clients/javer/src/javer/ChannelTab.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/GameMod.java
===================================================================
--- trunk/clients/javer/src/javer/GameMod.java 2005-04-12 02:39:42 UTC (rev
670)
+++ trunk/clients/javer/src/javer/GameMod.java 2005-04-25 00:49:04 UTC (rev
671)
@@ -0,0 +1,154 @@
+/*
+ * GameMod.java
+ *
+ * Created on January 14, 2005, 6:16 PM
+ */
+
+package javer;
+import java.util.*;
+import java.io.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+public abstract class GameMod extends HaverClient {
+
+ protected boolean connected = false;
+ protected boolean joined = false;
+ protected boolean playing = false;
+ protected boolean starting = false;
+ protected String channel = null;
+ protected Map channelMembers = null; /* UID -> nick */
+ protected Set players = null; /* UID */
+ protected Object joinTimer = null;
+
+ /** Creates a new instance of GameMod */
+ protected GameMod() {
+ }
+
+ protected void log(String level, String message) {
+ System.err.println(level + ": " + message);
+ }
+
+ public void dropPlayer(String requestor, String dropee) {
+ /* TODO */
+ }
+
+ protected void eventChannelPart(String where) throws IOException {
+ joined = false;
+ endGame();
+ channelMembers = null;
+ channel = null;
+ super.eventChannelPart(where);
+ }
+
+ protected void eventChannelJoin(String where) throws IOException {
+ if (joined) {
+ log("CRITICAL", "Joined an extra channel: " + where);
+ return;
+ }
+ joined = true;
+ channel = where;
+ listChannel(where);
+ super.eventChannelJoin(where);
+ }
+
+ protected boolean eventIOException(IOException e) {
+
+ boolean retValue;
+
+ retValue = super.eventIOException(e);
+ return retValue;
+ }
+
+ protected void eventIdentFailed(String why, String[] args) throws
IOException {
+
+ super.eventIdentFailed(why, args);
+ }
+
+ protected void eventChannelList(String where, Set names) throws
IOException {
+ Iterator it = names.iterator();
+ if (!where.equals(channel))
+ return;
+ channelMembers = new HashMap();
+ while (it.hasNext()) {
+ Object o = it.next();
+ channelMembers.put(o,o);
+ }
+ super.eventChannelList(where, names);
+ }
+
+ protected void eventNormalMessage(String where, String who, String arg)
throws IOException {
+ if (arg.equals("!join") && starting) {
+ if (players.contains(who)) {
+ sendPrivateNormalMessage(who, "You are already registered.");
+ } else {
+ players.add(who);
+ sendPrivateNormalMessage(who, "You are now registered.");
+ }
+ } else if (arg.equals("!abort") && (starting || playing)) {
+ abortGame();
+ } else if (arg.indexOf("!drop") == 0 && (starting || playing)) {
+ if (arg.length() == 0) {
+ dropPlayer(who, who);
+ } else {
+ if (arg.indexOf("!drop ") == 0) {
+ int i = "!drop ".length();
+ for (; i < arg.length(); i++) {
+ if (arg.charAt(i) != ' ')
+ break;
+ }
+ if (i != arg.length()) {
+ dropPlayer(who, arg.substring(i));
+ }
+ }
+ }
+ } else if (arg.equals("!start") && !(playing || starting)) {
+ starting = true;
+ players = new HashSet();
+ sendNormalMessage(where, "A new game has begun. Type !join in the
next 30 seconds to join.");
+ joinTimer = TimedInvoker.invokeAfter(30 * 1000, new Runnable() {
+ public void run () {
+ try {
+ beginGame();
+ } catch (IOException e) {
+ eventIOException(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ joinTimer = null;
+ }
+ });
+ }
+ super.eventNormalMessage(where, who, arg);
+ }
+
+ protected void eventDisconnected() throws IOException {
+ endGame();
+ super.eventDisconnected();
+ }
+
+ protected void eventIdentAccepted() throws IOException {
+ connected = true;
+ super.eventIdentAccepted();
+ }
+
+ public void endGame() throws IOException {
+ playing = starting = false;
+ players = null;
+ if (joinTimer != null) {
+ TimedInvoker.unschedule(joinTimer);
+ joinTimer = null;
+ }
+ }
+
+ public void abortGame() throws IOException {
+ endGame();
+ sendNormalMessage(channel, "Game aborted");
+ }
+
+ public void beginGame() throws IOException {
+ playing = true;
+ }
+}
Property changes on: trunk/clients/javer/src/javer/GameMod.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/HaverClient.java
===================================================================
--- trunk/clients/javer/src/javer/HaverClient.java 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/HaverClient.java 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,711 @@
+/*
+ * HaverClient.java
+ *
+ * Created on January 5, 2005, 8:14 PM
+ */
+
+package javer;
+import java.util.*;
+import java.io.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class HaverClient extends Thread {
+
+ protected java.lang.String versionString = "Javer/0.1";
+ protected java.net.Socket sock = null;
+ protected java.io.PrintWriter writer = null;
+ protected java.io.BufferedReader reader = null;
+ protected java.util.Map wants = new java.util.HashMap();
+ protected java.util.Map serverevents = new java.util.HashMap();
+ protected java.util.Map fails = new java.util.HashMap();
+ protected String uid = null;
+ protected Integer lock = new Integer(0);
+ protected Pinger pingDaemon = null;
+ protected List lagEvents = null;
+
+ protected void pushLagEvent() {
+ lagEvents.add(new Long(System.currentTimeMillis()));
+ if (pingDaemon != null)
+ pingDaemon.serverPoked();
+ }
+
+ protected void popLagEvent() {
+ try {
+ Long then = (Long)lagEvents.remove(0);
+ long delta = System.currentTimeMillis() - then.longValue();
+ eventLagMeasured(delta);
+ } catch (IOException e) {
+ eventIOException(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void send(String s) throws java.io.IOException {
+ synchronized (lock) {
+ if (sock == null) {
+ throw new IllegalStateException("Not connected to server");
+ }
+ writer.print(s + "\r\n");
+ writer.flush();
+ eventDebugMessage(">>> " + s);
+ }
+ }
+
+ protected void send(String[] s) throws java.io.IOException {
+ String tmp = "";
+ int i;
+ for (i = 0; i < s.length; i++) {
+ if (i != 0) {
+ tmp += "\t";
+ }
+ tmp += s[i];
+ }
+ send(tmp);
+ }
+
+ /** Creates a new instance of HaverClient */
+ public HaverClient() {
+ initFails();
+ initWants();
+ initServerEvents();
+ }
+
+ public void connect(String uid, java.net.Socket socket) throws
java.io.IOException {
+ this.sock = socket;
+ this.uid = uid;
+ NonblockingOutputStream s;
+ writer = new java.io.PrintWriter(
+ new java.io.OutputStreamWriter(
+ s = new NonblockingOutputStream(
+ new java.io.BufferedOutputStream(
+ sock.getOutputStream()
+ )
+ )
+ ));
+ s.setAutoFlush(true);
+ reader = new java.io.BufferedReader(
+ new java.io.InputStreamReader(
+ sock.getInputStream()
+ ));
+ send("HAVER\t" + versionString);
+ start();
+ lagEvents = Collections.synchronizedList(new java.util.LinkedList());
+ }
+
+ public String getUID() {
+ return uid;
+ }
+
+ public void connect(String uid, String hostname) throws
java.io.IOException {
+ connect(uid, hostname, 7070);
+ }
+
+ public void connect(String uid, String hostname, int port) throws
java.io.IOException {
+ java.net.Socket sock = new java.net.Socket(hostname, port);
+ connect(uid, sock);
+ }
+
+ public void run() {
+ while (sock.isConnected()) {
+ try {
+ String s = reader.readLine();
+ eventDebugMessage("<<< " + s);
+ synchronized (lock) {
+ if (reader == null)
+ return;
+ if (pingDaemon != null)
+ pingDaemon.serverResponse();
+ try {
+ dispatchCommand(s);
+ } catch (IOException e) {
+ throw e;
+ } catch (Exception e) {
+ e.printStackTrace();
+ // Dazed and confused, but trying to continue...
+ }
+ }
+ } catch (java.io.IOException e) {
+ if (!eventIOException(e)) {
+ disconnect();
+ return;
+ }
+ }
+ }
+ }
+
+ protected abstract class FailHandler {
+ public FailHandler() {}
+ public abstract void failure(String why, String[] args)
+ throws java.io.IOException;
+ }
+
+ protected abstract class ServerHandler {
+ public ServerHandler() {}
+ public abstract void trigger(String[] line) throws java.io.IOException;
+ }
+
+ protected abstract class WantHandler {
+ public WantHandler() {}
+ public abstract void trigger(String[] args) throws java.io.IOException;
+ }
+
+ protected void initFails() {
+ fails.put("IDENT", new FailHandler() {
+ public void failure(String why, String[] args) throws
java.io.IOException {
+ disconnect();
+ eventIdentFailed(why, args);
+ }
+ });
+ fails.put("PMSG", new FailHandler() {
+ public void failure(String why, String[] args) throws
java.io.IOException {
+ eventPrivateFailed(why, args);
+ }
+ });
+ fails.put("MSG", new FailHandler() {
+ public void failure(String why, String[] args) throws
java.io.IOException {
+ eventPublicFailed(why, args);
+ popLagEvent();
+ }
+ });
+ fails.put("LIST", new FailHandler() {
+ public void failure(String why, String[] args) throws
java.io.IOException {
+ /* XXX report to client */
+ popLagEvent();
+ }
+ });
+ fails.put("PART", new FailHandler() {
+ public void failure(String why, String[] args) throws
java.io.IOException {
+ /* XXX report to client */
+ popLagEvent();
+ }
+ });
+
+ }
+
+ protected void initWants() {
+ wants.put("IDENT", new WantHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ eventIdenting();
+ send("IDENT\t" + uid);
+ }
+ });
+ }
+
+ protected void initServerEvents() {
+ serverevents.put("WANT", new ServerHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ WantHandler h = (WantHandler) wants.get(args[1]);
+ if (h == null) {
+ send("CANT\t" + args[1]);
+ return;
+ }
+ h.trigger(args);
+ }
+ });
+ serverevents.put("ACCEPT", new ServerHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ eventIdentAccepted();
+ }
+ });
+ serverevents.put("MSG", new ServerHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ String[] msgArgs = subStringArray(args, 4, args.length - 1);
+ eventMessage(args[1], args[2], args[3], msgArgs);
+ if (args[2].equals(uid))
+ popLagEvent();
+ }
+ });
+ serverevents.put("PMSG", new ServerHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ String[] msgArgs = subStringArray(args, 3, args.length - 1);
+ eventPrivateMessage(args[1], args[2], msgArgs);
+ }
+ });
+ serverevents.put("JOIN", new ServerHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ if (args[2].equals(uid)) {
+ eventChannelJoin(args[1]);
+ } else {
+ eventChannelJoin(args[1], args[2]);
+ }
+ }
+ });
+ serverevents.put("PART", new ServerHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ if (args[2].equals(uid)) {
+ eventChannelPart(args[1]);
+ popLagEvent();
+ } else {
+ eventChannelPart(args[1], args[2]);
+ }
+ }
+ });
+ serverevents.put("QUIT", new ServerHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ eventQuit(args[1], args[2]);
+ }
+ });
+ serverevents.put("LIST", new ServerHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ Set s = new HashSet();
+ if (!args[2].equals("user")) {
+ /* we only know how to list for users right now */
+ return;
+ }
+ for (int i = 3; i < args.length; i++) {
+ s.add(args[i]);
+ }
+ eventChannelList(args[1], s);
+ popLagEvent();
+ }
+ });
+ serverevents.put("FAIL", new ServerHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ String cmd = args[1];
+ String why = args[2];
+ args = subStringArray(args, 3, args.length - 1);
+ eventCmdFailure(cmd, why, args);
+ }
+ });
+ serverevents.put("PING", new ServerHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ args = (String[]) args.clone();
+ args[0] = "PONG";
+ send(args);
+ }
+ });
+ serverevents.put("OUCH", new ServerHandler() {
+ public void trigger(String[] args) throws java.io.IOException {
+ long pingtime = Long.decode(args[2]).longValue();
+ long lag = System.currentTimeMillis() - pingtime;
+ eventLagMeasured(lag);
+ }
+ });
+ }
+
+ protected void dispatchCommand(String s) throws java.io.IOException {
+ String[] parts = s.split("\t");
+ ServerHandler h = (ServerHandler) serverevents.get(parts[0]);
+ if (h != null) {
+ h.trigger(parts);
+ }
+ }
+
+ public void join(String channel) throws java.io.IOException {
+ send("JOIN\t" + channel);
+ }
+
+ public void part(String channel) throws java.io.IOException {
+ pushLagEvent();
+ send("PART\t" + channel);
+ }
+
+ protected void eventIdentAccepted() throws java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventDebugMessage(String s) throws java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventDisconnected() throws java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventChannelJoin(String where) throws java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventChannelJoin(String where, String who) throws
java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventChannelPart(String where) throws java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventChannelPart(String where, String who) throws
java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventQuit(String who, String why) throws
java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventMessage(String where, String who, String type,
String[] args) throws java.io.IOException {
+ if (type.equals("\"")) {
+ eventNormalMessage(where, who, args[0]);
+ } else if (type.equals(":")) {
+ eventAction(where, who, args[0]);
+ } else if (type.equals("PING?")) {
+ sendPrivateMessage(who, "PING", args);
+ }
+ }
+
+ protected void eventNormalMessage(String where, String who, String arg)
throws java.io.IOException {
+ /* STUB */
+ }
+ protected void eventAction(String where, String who, String arg) throws
java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventPrivateMessage(String who, String type, String[] args)
throws java.io.IOException {
+ if (type.equals("\"")) {
+ eventPrivateNormalMessage(who, args[0]);
+ } else if (type.equals(":")) {
+ eventPrivateAction(who, args[0]);
+ } else if (type.equals("PING?")) {
+ sendPrivateMessage(who, "PING", args);
+ }
+ }
+
+ protected void eventPrivateNormalMessage(String who, String arg) throws
java.io.IOException {
+ /* STUB */
+ }
+ protected void eventPrivateAction(String who, String arg) throws
java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventChannelList(String where, Set names) throws
java.io.IOException {
+ /* STUB */
+ }
+
+ protected boolean eventCmdFailure(String cmd, String why, String[] args)
throws java.io.IOException {
+ if (fails.containsKey(cmd)) {
+ FailHandler h = (FailHandler) fails.get(cmd);
+ h.failure(why, args);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ protected void eventIdentFailed(String why, String[] args) throws
java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventPrivateFailed(String why, String[] args) throws
java.io.IOException {
+ /* STUB */
+ }
+
+ protected void eventPublicFailed(String why, String[] args) throws
java.io.IOException {
+ /* STUB */
+ }
+ public static final String[] subStringArray(String[] array, int start, int
end) {
+ if (start > end) {
+ return new String[0];
+ }
+ String[] newarray = new String[end - start + 1];
+ for (int i = 0; i <= end - start; i++) {
+ newarray[i] = array[start + i];
+ }
+ return newarray;
+ }
+
+ public void sendMessage(String where, String type, String message) throws
IOException {
+ pushLagEvent();
+ send("MSG\t" + where + "\t" + type + "\t" + message);
+ }
+
+ public void sendMessage(String where, String type, String[] message)
throws IOException {
+ String s = "MSG\t" + where + "\t" + type + "\t";
+ for (int i = 0; i < message.length; i++) {
+ s = s + message[i];
+ }
+ send(s);
+ }
+
+ public void sendNormalMessage(String where, String message) throws
IOException {
+ sendMessage(where, "\"", message);
+ }
+
+ public void sendAction(String where, String message) throws IOException {
+ sendMessage(where, ":", message);
+ }
+
+ public void sendPrivateMessage(String target, String type, String message)
throws IOException {
+ send("PMSG\t" + target + "\t" + type + "\t" + message);
+ }
+
+ public void sendPrivateMessage(String target, String type, String[]
message) throws IOException {
+ String s = "PMSG\t" + target + "\t" + type + "\t";
+ for (int i = 0; i < message.length; i++) {
+ s = s + message[i];
+ }
+ send(s);
+ }
+
+ public void sendPrivateNormalMessage(String target, String message) throws
IOException {
+ sendPrivateMessage(target, "\"", message);
+ }
+
+ public void sendPrivateAction(String target, String message) throws
IOException {
+ sendPrivateMessage(target, ":", message);
+ }
+
+ protected void eventIdenting() throws java.io.IOException {
+ /* STUB */
+ }
+
+ public void listChannel(String channel) throws IOException {
+ pushLagEvent();
+ send("LIST\t" + channel + "\tuser");
+ }
+
+ public void disconnect() {
+ if (sock == null)
+ return;
+ synchronized (lock) {
+ try {
+ sock.close();
+ } catch(Exception e) {}
+ sock = null;
+ reader = null;
+ writer = null;
+ uid = null;
+ try {
+ eventDisconnected();
+ } catch(IOException e) {}
+ }
+ }
+
+ public void pokeServer() throws IOException {
+ send("POKE\t" + System.currentTimeMillis());
+ if (pingDaemon != null)
+ pingDaemon.serverPoked();
+ }
+
+ /**
+ * Called when an I/O exception is detected internally, or caught from
+ * within an event handler.
+ *
+ *
+ * @param e
+ * @return true to remain connected; false to disconnect
+ */
+ protected boolean eventIOException(IOException e) {
+ return false;
+ }
+
+ protected class Pinger extends Thread {
+
+ /**
+ * Holds value of property pingInterval.
+ */
+ private int pingInterval;
+
+ /**
+ * Holds value of property deadInterval.
+ */
+ private int deadInterval;
+
+ /**
+ * Holds value of property lastPing.
+ */
+ private long lastPing;
+
+ private boolean halting = false;
+
+ private long lastPong;
+
+ public void run() {
+ while (true) {
+ long delta = 0;
+ this.interrupted(); /* we don't care if we're interrupted
+ * but we need the flag cleared
+ */
+ if (halting)
+ return;
+ long nextPing = Long.MAX_VALUE;
+ long nextDead = Long.MAX_VALUE;
+ long nextEvt;
+ long now = System.currentTimeMillis();
+ if (pingInterval > 0)
+ nextPing = lastPing + pingInterval;
+ else {
+ halting = true;
+ return;
+ }
+ if (deadInterval > 0)
+ nextDead = lastPong + deadInterval;
+
+ if (nextPing < nextDead)
+ nextEvt = nextPing;
+ else
+ nextEvt = nextDead;
+ /*System.out.println("lastPing=" + lastPing + " lastPong=" +
lastPong);
+ System.out.println("nextPing = " + nextPing + " nextDead = " +
nextDead + " nextEvt=" + nextEvt);
+ System.out.println("Now = " + now);
+ System.out.println("p="+nextPing+"\nn="+now);*/
+ if (now >= nextPing) {
+ try {
+ pokeServer();
+ } catch (IOException e) {
+ eventIOException(e);
+ }
+ nextPing = now + pingInterval;
+ continue;
+ }
+ if (now >= nextDead) {
+ try {
+ eventServerDead();
+ } catch (IOException e) {
+ eventIOException(e);
+ }
+ lastPong = now + deadInterval;
+ continue;
+ }
+ delta = nextEvt - now;
+ try {
+ //System.out.println("Sleeping for " + delta +"ms");
+ this.sleep(delta);
+ } catch(InterruptedException e) {}
+ }
+ }
+
+ /**
+ * Getter for property pingInterval.
+ * @return Value of property pingInterval.
+ */
+ public int getPingInterval() {
+
+ return this.pingInterval;
+ }
+
+ /**
+ * Setter for property pingInterval.
+ * @param pingInterval New value of property pingInterval.
+ */
+ public void setPingInterval(int pingInterval) {
+ if (pingInterval < 0)
+ throw new IllegalArgumentException("pingInterval must not be
negative");
+ if (deadInterval > pingInterval)
+ throw new IllegalArgumentException("pingInterval should be
greater than deadInterval");
+ synchronized (this) {
+ this.pingInterval = pingInterval;
+ if (pingInterval != 0) {
+ this.start();
+ this.interrupt();
+ } else {
+ this.halt();
+ }
+ }
+ }
+
+ /**
+ * Getter for property deadInterval.
+ * @return Value of property deadInterval.
+ */
+ public int getDeadInterval() {
+
+ return this.deadInterval;
+ }
+
+ /**
+ * Setter for property deadInterval.
+ * @param deadInterval New value of property deadInterval.
+ */
+ public void setDeadInterval(int deadInterval) {
+ if (deadInterval < 0)
+ throw new IllegalArgumentException("deadInterval must not be
negative");
+ if (deadInterval < pingInterval)
+ throw new IllegalArgumentException("pingInterval should be
greater than deadInterval");
+ synchronized (this) {
+ this.deadInterval = deadInterval;
+ if (pingInterval != 0) {
+ this.start();
+ this.interrupt();
+ } else {
+ this.halt();
+ }
+ }
+ }
+
+ /**
+ * Getter for property lastPing.
+ * @return Value of property lastPing.
+ */
+ public long getLastPing() {
+
+ return this.lastPing;
+ }
+
+ public Pinger(int pingInterval, int deadInterval) {
+ lastPing = lastPong = System.currentTimeMillis();
+ setPingInterval(pingInterval);
+ setDeadInterval(deadInterval);
+ }
+
+ public void halt() {
+ synchronized (this) {
+ halting = true;
+ if (this == Thread.currentThread())
+ return;
+ if (!this.isAlive())
+ return;
+ this.interrupt();
+ try {
+ this.join();
+ } catch (InterruptedException e) {
+ /* XXX */
+ }
+ }
+ }
+
+ public void serverResponse() {
+ synchronized (this) {
+ lastPong = System.currentTimeMillis();
+ }
+ }
+
+ public void serverPoked() {
+ synchronized (this) {
+ lastPing = System.currentTimeMillis();
+ }
+ }
+
+ public void start() {
+ if (this == Thread.currentThread())
+ return;
+ synchronized (this) {
+ if (this.isAlive()) {
+ if (halting) {
+ try {
+ this.join();
+ } catch (InterruptedException e) {
+ /* XXX */
+ }
+ }
+ else return;
+ }
+ super.start();
+ }
+ }
+ }
+
+ protected void eventServerDead() throws IOException {
+ /* STUB */
+ }
+
+ protected void eventLagMeasured(long lag) throws IOException {
+ /* STUB */
+ }
+
+ public void setPingTimers(int pingInterval, int deadInterval) {
+ if (pingDaemon == null) {
+ pingDaemon = new Pinger(pingInterval * 1000, deadInterval * 1000);
+ return;
+ }
+ pingDaemon.setDeadInterval(0); /* XXX: prevent exception when new
+ * deadInterval > old pingInterval
+ * needs to be cleaner
+ */
+ pingDaemon.setPingInterval(pingInterval * 1000);
+ pingDaemon.setDeadInterval(deadInterval * 1000);
+ }
+
+}
Property changes on: trunk/clients/javer/src/javer/HaverClient.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/JaverApplet.java
===================================================================
--- trunk/clients/javer/src/javer/JaverApplet.java 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/JaverApplet.java 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,157 @@
+/*
+ * JaverApplet.java
+ *
+ * Created on January 6, 2005, 11:22 PM
+ */
+
+package javer;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class JaverApplet extends javax.swing.JApplet {
+
+ Panel panel = null;
+ String[] autojoin = null;
+
+ /** Creates a new instance of JaverApplet */
+ public JaverApplet() {
+ super();
+ }
+
+ /**
+ * Called by the browser or applet viewer to inform
+ * this applet that it should stop its execution. It is called when
+ * the Web page that contains this applet has been replaced by
+ * another page, and also just before the applet is to be destroyed.
+ * <p>
+ * A subclass of <code>Applet</code> should override this method if
+ * it has any operation that it wants to perform each time the Web
+ * page containing it is no longer visible. For example, an applet
+ * with animation might want to use the <code>start</code> method to
+ * resume animation, and the <code>stop</code> method to suspend the
+ * animation.
+ * <p>
+ * The implementation of this method provided by the
+ * <code>Applet</code> class does nothing.
+ *
+ * @see java.applet.Applet#destroy()
+ * @see java.applet.Applet#init()
+ */
+ public void stop() {
+ /* appletviewer calls this when we switch desktops.
+ * appletviewer sucks.
+ */
+ panel.do_disconnect();
+ super.stop();
+ }
+
+ /**
+ * Called by the browser or applet viewer to inform
+ * this applet that it has been loaded into the system. It is always
+ * called before the first time that the <code>start</code> method is
+ * called.
+ * <p>
+ * A subclass of <code>Applet</code> should override this method if
+ * it has initialization to perform. For example, an applet with
+ * threads would use the <code>init</code> method to create the
+ * threads and the <code>destroy</code> method to kill them.
+ * <p>
+ * The implementation of this method provided by the
+ * <code>Applet</code> class does nothing.
+ *
+ * @see java.applet.Applet#destroy()
+ * @see java.applet.Applet#start()
+ * @see java.applet.Applet#stop()
+ */
+ public void init() {
+ String host;
+ int port;
+ String autojoin_str;
+ super.init();
+ System.out.println("init");
+ host = this.getParameter("hostname");
+ port = Integer.decode(this.getParameter("port")).intValue();
+ autojoin_str = this.getParameter("autojoin");
+ System.out.println("autojoin = " + autojoin_str);
+ if (autojoin_str != null) {
+ autojoin = autojoin_str.split("[, ]+");
+ System.out.println("count = " + autojoin.length);
+ } else {
+ autojoin = null;
+ }
+ panel = new Panel(this, host, port);
+ getContentPane().setLayout(new java.awt.GridLayout(1,0));
+ getContentPane().add(panel);
+ }
+
+ /**
+ * Called by the browser or applet viewer to inform
+ * this applet that it is being reclaimed and that it should destroy
+ * any resources that it has allocated. The <code>stop</code> method
+ * will always be called before <code>destroy</code>.
+ * <p>
+ * A subclass of <code>Applet</code> should override this method if
+ * it has any operation that it wants to perform before it is
+ * destroyed. For example, an applet with threads would use the
+ * <code>init</code> method to create the threads and the
+ * <code>destroy</code> method to kill them.
+ * <p>
+ * The implementation of this method provided by the
+ * <code>Applet</code> class does nothing.
+ *
+ * @see java.applet.Applet#init()
+ * @see java.applet.Applet#start()
+ * @see java.applet.Applet#stop()
+ */
+ public void destroy() {
+ panel.do_disconnect();
+ super.destroy();
+ }
+
+ protected final class Panel extends JaverUIPanel {
+ JaverApplet applet;
+ public Panel(
+ JaverApplet a,
+ String hostname,
+ int port) {
+ super(hostname, port);
+ System.out.println("subclass panel init");
+ this.applet = a;
+ }
+
+ public boolean processLine(String query) {
+
+ boolean retValue;
+
+ retValue = super.processLine(query);
+ return retValue;
+ }
+
+ protected Client spawnClient() {
+ return new SubClient(this);
+ }
+
+ protected final class SubClient extends javer.JaverUIPanel.Client {
+ public SubClient(JaverUIPanel panel) {
+ super(panel);
+ }
+
+ protected void eventIdentAccepted() throws java.io.IOException {
+ super.eventIdentAccepted();
+ System.out.println("check autojoin");
+ if (autojoin != null) {
+ int i;
+ for (i = 0; i < autojoin.length; i++) {
+ putServer("Auto-joining " + autojoin[i]);
+ cli.join(autojoin[i]);
+ }
+ }
+ }
+ }
+
+ }
+
+
+}
Property changes on: trunk/clients/javer/src/javer/JaverApplet.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/JaverUI.form
===================================================================
--- trunk/clients/javer/src/javer/JaverUI.form 2005-04-12 02:39:42 UTC (rev
670)
+++ trunk/clients/javer/src/javer/JaverUI.form 2005-04-25 00:49:04 UTC (rev
671)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.FrameFormInfo">
+ <SyntheticProperties>
+ <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+ </SyntheticProperties>
+ <Events>
+ <EventHandler event="windowClosing"
listener="java.awt.event.WindowListener"
parameters="java.awt.event.WindowEvent" handler="exitForm"/>
+ </Events>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
+</Form>
Added: trunk/clients/javer/src/javer/JaverUI.java
===================================================================
--- trunk/clients/javer/src/javer/JaverUI.java 2005-04-12 02:39:42 UTC (rev
670)
+++ trunk/clients/javer/src/javer/JaverUI.java 2005-04-25 00:49:04 UTC (rev
671)
@@ -0,0 +1,85 @@
+/*
+ * JaverUI.java
+ *
+ * Created on January 5, 2005, 9:27 PM
+ */
+
+package javer;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class JaverUI extends java.awt.Frame {
+
+ /** Creates new form JaverUI */
+ public JaverUI() {
+ addWindowListener(new CloseListener());
+ add(new JaverUIPanel("odin.haverdev.org", 7070));
+ pack();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ private void initComponents() {//GEN-BEGIN:initComponents
+
+ setLayout(new javax.swing.BoxLayout(this,
javax.swing.BoxLayout.X_AXIS));
+
+ addWindowListener(new java.awt.event.WindowAdapter() {
+ public void windowClosing(java.awt.event.WindowEvent evt) {
+ exitForm(evt);
+ }
+ });
+
+ pack();
+ }//GEN-END:initComponents
+
+ /** Exit the Application */
+ private void exitForm(java.awt.event.WindowEvent evt)
{//GEN-FIRST:event_exitForm
+ System.exit(0);
+ }//GEN-LAST:event_exitForm
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new JaverUI().setVisible(true);
+ }
+ });
+ }
+
+ private final class CloseListener implements java.awt.event.WindowListener
{
+ public void windowOpened(java.awt.event.WindowEvent e) {
+ }
+
+ public void windowIconified(java.awt.event.WindowEvent e) {
+ }
+
+ public void windowDeiconified(java.awt.event.WindowEvent e) {
+ }
+
+ public void windowDeactivated(java.awt.event.WindowEvent e) {
+ }
+
+ public void windowClosing(java.awt.event.WindowEvent e) {
+ System.exit(0);
+ }
+
+ public void windowClosed(java.awt.event.WindowEvent e) {
+ }
+
+ public void windowActivated(java.awt.event.WindowEvent e) {
+ }
+ }
+
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ // End of variables declaration//GEN-END:variables
+
+}
Property changes on: trunk/clients/javer/src/javer/JaverUI.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/JaverUIPanel.form
===================================================================
--- trunk/clients/javer/src/javer/JaverUIPanel.form 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/JaverUIPanel.form 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.PanelFormInfo">
+
+ <Layout
class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JTabbedPane" name="jTabbedPane1">
+ <Properties>
+ <Property name="tabLayoutPolicy" type="int" value="1"/>
+ <Property name="tabPlacement" type="int" value="3"/>
+ </Properties>
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"
value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="Center"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout
class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
+ </Container>
+ <Container class="javax.swing.JPanel" name="jPanel2">
+ <AuxValues>
+ <AuxValue name="JavaCodeGenerator_VariableModifier"
type="java.lang.Integer" value="0"/>
+ <AuxValue name="JavaCodeGenerator_VariableLocal"
type="java.lang.Boolean" value="true"/>
+ </AuxValues>
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"
value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="South"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout
class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
+ <Property name="axis" type="int" value="1"/>
+ </Layout>
+ <SubComponents>
+ <Component class="javax.swing.JTextField" name="input">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="jTextField1"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed"
listener="java.awt.event.ActionListener"
parameters="java.awt.event.ActionEvent" handler="inputActionPerformed"/>
+ <EventHandler event="keyTyped"
listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent"
handler="inputKeyTyped"/>
+ </Events>
+ </Component>
+ <Container class="javax.swing.JPanel" name="jPanel1">
+ <AuxValues>
+ <AuxValue name="JavaCodeGenerator_VariableModifier"
type="java.lang.Integer" value="0"/>
+ <AuxValue name="JavaCodeGenerator_VariableLocal"
type="java.lang.Boolean" value="true"/>
+ </AuxValues>
+
+ <Layout
class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
+ <Property name="columns" type="int" value="2"/>
+ <Property name="rows" type="int" value="1"/>
+ </Layout>
+ <SubComponents>
+ <Component class="javax.swing.JLabel" name="status">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="NOT
CONNECTED"/>
+ <Property name="minimumSize" type="java.awt.Dimension"
editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[300, 300]"/>
+ </Property>
+ </Properties>
+ </Component>
+ <Component class="javax.swing.JLabel" name="lagLabel">
+ <Properties>
+ <Property name="horizontalAlignment" type="int" value="4"/>
+ </Properties>
+ </Component>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+</Form>
Added: trunk/clients/javer/src/javer/JaverUIPanel.java
===================================================================
--- trunk/clients/javer/src/javer/JaverUIPanel.java 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/JaverUIPanel.java 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,587 @@
+/*
+ * JaverUIPanel.java
+ *
+ * Created on January 5, 2005, 9:31 PM
+ */
+
+package javer;
+import java.io.*;
+import java.util.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class JaverUIPanel extends java.awt.Panel {
+
+ protected Client cli = null;
+ protected String host = null;
+ protected String uid = null;
+ protected int port = 7070;
+ protected Map commands = new HashMap();
+ protected Map tabs = new HashMap();
+ protected Map channelTabs = new HashMap();
+ protected Map userTabs = new HashMap();
+ protected Map tabToPair = new HashMap();
+ protected TabPair serverTabPair = new TabPair();
+ protected SimpleTextTab serverTab = new SimpleTextTab();
+
+ protected Client spawnClient() {
+ return new Client(this);
+ }
+
+ /** Creates new form JaverUIPanel */
+ public JaverUIPanel(String hostname, int port) {
+ this.host = hostname;
+ this.port = port;
+ initCommands();
+ initComponents();
+ serverTabPair.tab = serverTab;
+ serverTabPair.title = "Server";
+ addTab(serverTabPair);
+ do_disconnect();
+ }
+
+ protected abstract class CommandHandler {
+ public CommandHandler () {}
+ abstract boolean trigger(String arg) throws IOException;
+ }
+
+ public final class TabPair {
+ java.awt.Component tab;
+ int index;
+ String title;
+ }
+
+ protected void addTab(TabPair p) {
+ p.index = jTabbedPane1.getTabCount();
+ jTabbedPane1.addTab(p.title, p.tab);
+ jTabbedPane1.setSelectedIndex(p.index);
+ tabs.put(p.title, p);
+ tabToPair.put(p.tab, p);
+ }
+
+ protected TabPair findTab(String tag) {
+ TabPair t = (TabPair) tabs.get(tag);
+ return t;
+ }
+
+ protected void killTab(TabPair p) {
+ Iterator it;
+ if (p == null || !tabs.containsValue(p))
+ return;
+ jTabbedPane1.removeTabAt(p.index);
+ tabs.remove(p.title);
+ it = tabs.values().iterator();
+ while (it.hasNext()) {
+ TabPair x = (TabPair) it.next();
+ if (x.index > p.index) {
+ x.index--;
+ }
+ }
+ try {
+ channelTabs.remove(((ChannelTab)p.tab).getChannel());
+ } catch (ClassCastException e) {}
+ try {
+ userTabs.remove(((UserQueryTab)p.tab).getUID());
+ } catch (ClassCastException e) {}
+ tabToPair.remove(p.tab);
+ }
+
+ protected void killTab(java.awt.Component t) {
+ TabPair p = (TabPair)tabToPair.get(t);
+ if (p.index == 0)
+ return;
+ killTab(p);
+ }
+
+ protected UserQueryTab getQuery(String who) {
+ TabPair p = (TabPair)userTabs.get(who);
+ if (p != null)
+ return (UserQueryTab)p.tab;
+ p = new TabPair();
+ p.title = "Query: " + who;
+ p.tab = new UserQueryTab(cli, who);
+ addTab(p);
+ userTabs.put(who, p);
+ return (UserQueryTab)p.tab;
+ }
+
+ public class Client extends HaverClient {
+ JaverUIPanel panel;
+
+ public Client(JaverUIPanel panel) {
+ this.panel = panel;
+ }
+
+ protected void eventDebugMessage(String s) throws java.io.IOException {
+ System.out.println(s);
+ super.eventDebugMessage(s);
+ }
+
+ protected void eventIdentAccepted() throws java.io.IOException {
+ putServer("Logged in successfully.");
+ status.setText("Connected.");
+ super.eventIdentAccepted();
+ setPingTimers(60, 180);
+ pokeServer();
+ }
+
+ protected void eventIdenting() throws java.io.IOException {
+ putServer("Logging in...");
+ super.eventIdenting();
+ }
+
+ protected void eventChannelPart(String where) throws
java.io.IOException {
+ killTab((TabPair)channelTabs.get(where));
+ channelTabs.remove(where);
+ super.eventChannelPart(where);
+ }
+
+ protected void eventChannelJoin(String where) throws
java.io.IOException {
+ TabPair t = (TabPair) channelTabs.get(where);
+ if (t == null) {
+ t = new TabPair();
+ t.tab = new ChannelTab(panel, cli, where);
+ t.title = "Channel: " + where;
+ addTab(t);
+ channelTabs.put(where, t);
+ }
+ QueryTab qt = (QueryTab) t.tab;
+ qt.putText("--- Joined " + where);
+ cli.listChannel(where);
+ super.eventChannelJoin(where);
+ }
+
+ protected void eventMessage(String where, String who, String type,
String[] args) throws java.io.IOException {
+
+ super.eventMessage(where, who, type, args);
+ }
+
+ protected void eventChannelList(String where, Set names) throws
java.io.IOException {
+ ChannelTab tab;
+ TabPair t = (TabPair) channelTabs.get(where);
+ if (t == null)
+ return;
+ tab = (ChannelTab) t.tab;
+ tab.setUsers(names);
+ super.eventChannelList(where, names);
+ }
+
+ protected void eventQuit(String who, String why) throws
java.io.IOException {
+ Iterator it = tabs.values().iterator();
+ while (it.hasNext()) {
+ ChannelTab tab;
+ try {
+ tab = (ChannelTab) ((TabPair)it.next()).tab;
+ } catch (ClassCastException e) {
+ continue;
+ }
+ if (!tab.hasUser(who))
+ continue;
+ tab.putText("--- " + who + " has quit (" + why + ")");
+ tab.delUser(who);
+ }
+ super.eventQuit(who, why);
+ }
+
+ protected void eventNormalMessage(String where, String who, String
arg) throws java.io.IOException {
+ TextTab tab;
+ TabPair t = (TabPair) channelTabs.get(where);
+ if (t == null)
+ return;
+ tab = (TextTab) t.tab;
+ tab.putText("<" + who + "> " + arg);
+ super.eventNormalMessage(where, who, arg);
+ }
+
+ protected void eventChannelPart(String where, String who) throws
java.io.IOException {
+ ChannelTab tab;
+ TabPair t = (TabPair) channelTabs.get(where);
+ if (t == null)
+ return;
+ tab = (ChannelTab) t.tab;
+ tab.delUser(who);
+ tab.putText("--- " + who + " has left.");
+ super.eventChannelPart(where, who);
+ }
+
+ protected void eventChannelJoin(String where, String who) throws
java.io.IOException {
+ ChannelTab tab;
+ TabPair t = (TabPair) channelTabs.get(where);
+ if (t == null)
+ return;
+ tab = (ChannelTab) t.tab;
+ tab.addUser(who);
+ tab.putText("--- " + who + " has joined.");
+ super.eventChannelJoin(where, who);
+ }
+
+ protected void eventAction(String where, String who, String arg)
throws java.io.IOException {
+ TextTab tab;
+ TabPair t = (TabPair) channelTabs.get(where);
+ if (t == null)
+ return;
+ tab = (TextTab) t.tab;
+ tab.putText("* " + who + " " + arg);
+ super.eventAction(where, who, arg);
+ }
+
+ protected void eventPrivateMessage(String who, String type, String[]
args) throws java.io.IOException {
+
+ super.eventPrivateMessage(who, type, args);
+ }
+
+ protected void eventPrivateNormalMessage(String who, String arg)
throws java.io.IOException {
+ getQuery(who).putText("<" + who + "> " + arg);
+ super.eventPrivateNormalMessage(who, arg);
+ }
+
+ protected void eventPrivateAction(String who, String arg) throws
java.io.IOException {
+ getQuery(who).putText("* " + who + " " + arg);
+ super.eventPrivateAction(who, arg);
+ }
+
+ protected boolean eventIOException(IOException e) {
+ putServer("I/O exception: " + e.getLocalizedMessage());
+ return false;
+ }
+
+ protected void eventPublicFailed(String why, String[] args) throws
IOException {
+ TextTab tab;
+ if (channelTabs.containsKey(args[0])) {
+ TabPair p = (TabPair) channelTabs.get(args[0]);
+ tab = (TextTab) p.tab;
+ } else {
+ tab = serverTab;
+ }
+ tab.putText("Public message failed: " + why + ", args: " + args);
+ super.eventPublicFailed(why, args);
+ }
+
+ protected void eventPrivateFailed(String why, String[] args) throws
IOException {
+ TextTab tab;
+ if (userTabs.containsKey(args[0])) {
+ tab = getQuery(args[0]);
+ } else {
+ tab = serverTab;
+ }
+ tab.putText("Private message failed: " + why + ", args: " + args);
+ super.eventPrivateFailed(why, args);
+ }
+
+ protected void eventIdentFailed(String why, String[] args) throws
IOException {
+ putServer("Login failed: " + why + ", args: " + args);
+ super.eventIdentFailed(why, args);
+ disconnect();
+ }
+
+ protected boolean eventCmdFailure(String cmd, String why, String[]
args) throws IOException {
+
+ boolean retValue;
+
+ retValue = super.eventCmdFailure(cmd, why, args);
+ if (retValue)
+ return retValue;
+
+ putServer("Unknown failure event. Command: " + cmd +
+ ", reason: " + why + ", args: " + args);
+
+ return false;
+ }
+
+ protected void eventDisconnected() throws IOException {
+ do_disconnect();
+ super.eventDisconnected();
+ }
+
+ protected void eventServerDead() throws IOException {
+ putServer("Server seems to be dead, killing connection.");
+ do_disconnect();
+ super.eventServerDead();
+ }
+
+ protected void eventLagMeasured(long lag) throws IOException {
+ double dlag = lag / 1000.0;
+ lagLabel.setText("Current lag: " + dlag);
+ super.eventLagMeasured(lag);
+ }
+
+ }
+
+
+ public void activateQuery(String who) {
+ UserQueryTab t = getQuery(who);
+ jTabbedPane1.setSelectedComponent(t);
+ }
+
+ public void do_disconnect() {
+ /* XXX: split this into disconnect-performing and after-disconnect
+ * functions
+ */
+ Set pairs = new java.util.HashSet(tabs.values());
+ Iterator it = pairs.iterator();
+ while (it.hasNext()) {
+ TabPair p = (TabPair) it.next();
+ if (p != serverTabPair) {
+ killTab(p);
+ }
+ }
+ if (cli != null) {
+ cli.disconnect();
+ cli = null;
+ }
+ serverTab.putText(
+ "Welcome to haver!\n\n" +
+ "Enter your UID to begin."
+ );
+ status.setText("NOT CONNECTED");
+ lagLabel.setText("");
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ private void initComponents() {//GEN-BEGIN:initComponents
+ javax.swing.JPanel jPanel1;
+ javax.swing.JPanel jPanel2;
+
+ jTabbedPane1 = new javax.swing.JTabbedPane();
+ jPanel2 = new javax.swing.JPanel();
+ input = new javax.swing.JTextField();
+ jPanel1 = new javax.swing.JPanel();
+ status = new javax.swing.JLabel();
+ lagLabel = new javax.swing.JLabel();
+
+ setLayout(new java.awt.BorderLayout());
+
+
jTabbedPane1.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
+ jTabbedPane1.setTabPlacement(javax.swing.JTabbedPane.BOTTOM);
+ add(jTabbedPane1, java.awt.BorderLayout.CENTER);
+
+ jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2,
javax.swing.BoxLayout.Y_AXIS));
+
+ input.setText("jTextField1");
+ input.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ inputActionPerformed(evt);
+ }
+ });
+ input.addKeyListener(new java.awt.event.KeyAdapter() {
+ public void keyTyped(java.awt.event.KeyEvent evt) {
+ inputKeyTyped(evt);
+ }
+ });
+
+ jPanel2.add(input);
+
+ jPanel1.setLayout(new java.awt.GridLayout(1, 2));
+
+ status.setText("NOT CONNECTED");
+ status.setMinimumSize(new java.awt.Dimension(300, 300));
+ jPanel1.add(status);
+
+ lagLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
+ jPanel1.add(lagLabel);
+
+ jPanel2.add(jPanel1);
+
+ add(jPanel2, java.awt.BorderLayout.SOUTH);
+
+ }//GEN-END:initComponents
+
+ private void inputKeyTyped(java.awt.event.KeyEvent evt)
{//GEN-FIRST:event_inputKeyTyped
+ if (evt.getKeyChar() != '\n')
+ return;
+ if (cli == null) {
+ putServer("Connecting...");
+ status.setText("Connecting...");
+ cli = spawnClient();
+ try {
+ cli.connect(uid = input.getText(), host, port);
+ input.setText("");
+ putServer("Connected...");
+ return;
+ } catch (IOException e) {
+ putServer("Failed: " + e.getLocalizedMessage());
+ status.setText("NOT CONNECTED");
+ return;
+ }
+ }
+ String query = input.getText();
+ input.setText("");
+ if (!processLine(query)) {
+ try {
+ TextTab tab = (TextTab) jTabbedPane1.getSelectedComponent();
+ tab.putText("--- Erroneous command: " + query);
+ } catch (ClassCastException e) {
+ putServer("--- Erroneous command: " + query);
+ }
+ }
+ }//GEN-LAST:event_inputKeyTyped
+
+ private void inputActionPerformed(java.awt.event.ActionEvent evt)
{//GEN-FIRST:event_inputActionPerformed
+ // TODO add your handling code here:
+ }//GEN-LAST:event_inputActionPerformed
+
+ protected void putServer(String s) {
+ serverTab.putText(s);
+ }
+
+ protected void initCommands() {
+ commands.put("me", new CommandHandler() {
+ boolean trigger(String arg) throws IOException {
+ try {
+ QueryTab q = (QueryTab)
jTabbedPane1.getSelectedComponent();
+ q.sendAction(arg);
+ return true;
+ } catch(ClassCastException e) {
+ return false;
+ }
+ }
+ });
+ commands.put("join", new CommandHandler() {
+ boolean trigger(String arg) throws IOException {
+ if (channelTabs.containsKey(arg))
+ return true;
+ cli.join(arg);
+ return true;
+ }
+ });
+ commands.put("part", new CommandHandler() {
+ boolean trigger(String arg) throws IOException {
+ if (arg == "") {
+ try {
+ ChannelTab t;
+ t = (ChannelTab) jTabbedPane1.getSelectedComponent();
+ arg = t.getChannel();
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+ if (!channelTabs.containsKey(arg))
+ return true;
+ cli.part(arg);
+ return true;
+ }
+ });
+ commands.put("quit", new CommandHandler() {
+ boolean trigger(String arg) {
+ System.exit(0);
+ return false;
+ }
+ });
+ commands.put("query", new CommandHandler() {
+ boolean trigger(String arg) {
+ UserQueryTab tab = getQuery(arg);
+ jTabbedPane1.setSelectedComponent(tab);
+ return true;
+ }
+ });
+ commands.put("msg", new CommandHandler() {
+ boolean trigger(String arg) throws IOException {
+ UserQueryTab tab;
+ String who, what;
+ int space = arg.indexOf(' ');
+ if (space == -1)
+ return false;
+ who = arg.substring(0, space);
+ what = arg.substring(space + 1);
+
+ tab = getQuery(who);
+ tab.sendText(what);
+ return true;
+ }
+ });
+ commands.put("say", new CommandHandler() {
+ boolean trigger(String arg) throws IOException {
+ try {
+ QueryTab q = (QueryTab)
jTabbedPane1.getSelectedComponent();
+ q.sendText(arg);
+ return true;
+ } catch(ClassCastException e) {
+ return false;
+ }
+ }
+ });
+ commands.put("", commands.get("say"));
+ commands.put("act", new CommandHandler() {
+ boolean trigger(String arg) throws IOException {
+ UserQueryTab tab;
+ String who, what;
+ int space = arg.indexOf(' ');
+ if (space == -1)
+ return false;
+ who = arg.substring(0, space);
+ what = arg.substring(space + 1);
+
+ tab = getQuery(who);
+ tab.sendAction(what);
+ return true;
+ }
+ });
+ commands.put("close", new CommandHandler() {
+ boolean trigger(String arg) throws IOException {
+ try {
+ ChannelTab q = (ChannelTab)
jTabbedPane1.getSelectedComponent();
+ cli.part(q.getChannel());
+ return true;
+ } catch (ClassCastException e) {}
+ killTab(jTabbedPane1.getSelectedComponent());
+ return true;
+ }
+ });
+ }
+
+ public boolean processLine(String query) {
+ try {
+ if (query.charAt(0) == '/' || query.charAt(0) == '.') {
+ String command, arg;
+ int endcommand = query.indexOf(' ');
+ if (endcommand == -1) {
+ command = query.substring(1);
+ arg = "";
+ } else {
+ command = query.substring(1, endcommand);
+ arg = query.substring(endcommand + 1);
+ }
+ System.out.println("COMMAND: " + command + " ARG: " + arg);
+ if (!commands.containsKey(command.toLowerCase()))
+ return false;
+ System.out.println("triggering\n");
+ return ((CommandHandler)commands.get(command)).trigger(arg);
+ }
+ try {
+ QueryTab tab = (QueryTab) jTabbedPane1.getSelectedComponent();
+ int i;
+ if (query.indexOf(';') != 0) {
+ tab.sendText(query);
+ return true;
+ }
+ for (i = 1; i < query.length(); i++) {
+ if (query.charAt(i) != ' ')
+ break;
+ }
+ query = query.substring(i);
+ tab.sendAction(query);
+ return true;
+ } catch (java.lang.ClassCastException ex) {
+ return true;
+ }
+ } catch (IOException e) {
+ cli.eventIOException(e);
+ do_disconnect();
+ }
+ return false;
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JTextField input;
+ private javax.swing.JTabbedPane jTabbedPane1;
+ private javax.swing.JLabel lagLabel;
+ private javax.swing.JLabel status;
+ // End of variables declaration//GEN-END:variables
+
+}
Property changes on: trunk/clients/javer/src/javer/JaverUIPanel.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/NonblockingOutputStream.java
===================================================================
--- trunk/clients/javer/src/javer/NonblockingOutputStream.java 2005-04-12
02:39:42 UTC (rev 670)
+++ trunk/clients/javer/src/javer/NonblockingOutputStream.java 2005-04-25
00:49:04 UTC (rev 671)
@@ -0,0 +1,201 @@
+/*
+ * NonblockingOutputStream.java
+ *
+ * Created on January 10, 2005, 1:53 PM
+ */
+
+package javer;
+import java.io.*;
+import java.util.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class NonblockingOutputStream extends java.io.FilterOutputStream
+ implements Runnable {
+
+ protected Vector preflush, pending;
+ protected long active_len;
+ protected long pending_len;
+ protected long preflush_len;
+ protected boolean flushing, closing, autoflush;
+ protected IOException pending_exception = null;
+ protected Thread th;
+ protected OutputStream out;
+
+ public NonblockingOutputStream(OutputStream out) {
+ super(out);
+ this.out = out;
+ flushing = closing = autoflush = false;
+ preflush = null;
+ pending = new Vector();
+ active_len = pending_len = preflush_len = 0;
+ th = new Thread(this);
+ th.start();
+ }
+
+ public void run() {
+ if (Thread.currentThread() != th)
+ throw new IllegalStateException("run() must be executed from
within " +
+ "NonblockingOutputStream.th");
+ try {
+ while (true) {
+ Vector work;
+ boolean flushafter = false;
+ synchronized (th) {
+ active_len = 0;
+ if (flushing) {
+ flushafter = true;
+ flushing = false;
+
+ }
+ work = pending;
+ pending = new Vector();
+ active_len = pending_len;
+ pending_len = 0;
+ if (flushing) {
+ flushafter = true;
+ flushing = false;
+ pending = preflush;
+ pending_len = preflush_len;
+ preflush_len = 0;
+ preflush = null;
+ } else if (active_len == 0) {
+ //System.out.println("active_len == 0, blocking");
+ if (autoflush) {
+ out.flush();
+ }
+ if (closing) {
+ out.close();
+ return;
+ }
+ try {
+ th.wait();
+ } catch (InterruptedException e) {}
+ //System.out.println("done blocking");
+ continue;
+ }
+ }
+ Iterator it;
+ //System.out.println("writing, active_len = " + active_len);
+ it = work.iterator();
+ while (it.hasNext()) {
+ byte[] b = (byte[]) it.next();
+ out.write(b);
+ }
+ if (flushafter)
+ out.flush();
+ }
+ } catch (IOException e) {
+ synchronized(th) {
+ pending_exception = e;
+ }
+ }
+ }
+
+ public void write(byte[] b) throws IOException {
+ if (b.length == 0)
+ return;
+ //System.out.println("write called");
+ synchronized(th) {
+ if (pending_exception != null)
+ throw pending_exception;
+ if (flushing) {
+ preflush.add(b);
+ preflush_len += b.length;
+ } else {
+ pending.add(b);
+ pending_len += b.length;
+ th.notifyAll();
+ }
+ dump();
+ }
+ }
+
+ public void close() throws IOException {
+ synchronized(th) {
+ if (pending_exception != null)
+ throw pending_exception;
+ closing = true;
+ th.notifyAll();
+ dump();
+ }
+ }
+
+ public void flush() throws IOException {
+ synchronized(th) {
+ if (pending_exception != null)
+ throw pending_exception;
+ /* if we'return autoflushing, eventually a buffer will fill
somewhere
+ * and cause a flush, or else autoFlush will kick in. So the manual
+ * flush() is redundant
+ */
+ if (autoflush)
+ return;
+ flushing = true;
+ preflush = new Vector();
+ preflush_len = 0;
+ th.notifyAll();
+ dump();
+ }
+ }
+
+ /**
+ * Getter for property autoFlush.
+ * @return Value of property autoFlush.
+ */
+ public boolean isAutoFlush() {
+ return autoflush;
+ }
+
+ /**
+ * Setter for property autoFlush.
+ * @param autoFlush New value of property autoFlush.
+ */
+ public void setAutoFlush(boolean autoFlush) {
+ synchronized (th) {
+ autoflush = true;
+ th.notify();
+ }
+ }
+
+ protected void dump() {
+ /*
+ System.out.println("=== NonblockingOutputStream status:");
+ synchronized(th) {
+ System.out.println("Flags: flushing="+flushing+"
closing="+closing+" autoflush="+autoflush);
+ System.out.println("Buffer levels: preflush_len=" + preflush_len +
" pending_len="+pending_len);
+ System.out.print("Vector element counts: ");
+ if (preflush == null) {
+ System.out.print("preflush={null}" );
+ } else {
+ System.out.print("preflush=" + preflush.size());
+ }
+ System.out.println("pending=" + pending.size());
+ }
+ System.out.println("Stack trace:");
+ new Exception().printStackTrace();
+ */
+ }
+
+ public void write(int b) throws IOException {
+ byte[] a = new byte[1];
+ a[0] = (byte) b;
+ write(a);
+ }
+
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (len == 0)
+ return;
+ if (len < 0)
+ throw new IllegalArgumentException("len must not be negative");
+ if (off + len > b.length)
+ throw new IllegalArgumentException("off + len > b.length");
+ byte[] buffer = new byte[len];
+ int i;
+ for (i = 0; i < len; i++)
+ buffer[i] = b[off + i];
+ write(buffer);
+ }
+}
Property changes on: trunk/clients/javer/src/javer/NonblockingOutputStream.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/QueryTab.java
===================================================================
--- trunk/clients/javer/src/javer/QueryTab.java 2005-04-12 02:39:42 UTC (rev
670)
+++ trunk/clients/javer/src/javer/QueryTab.java 2005-04-25 00:49:04 UTC (rev
671)
@@ -0,0 +1,16 @@
+/*
+ * QueryTab.java
+ *
+ * Created on January 6, 2005, 12:43 AM
+ */
+
+package javer;
+
+/**
+ *
+ * @author bdonlan
+ */
+public interface QueryTab extends TextTab {
+ public void sendText(String s) throws java.io.IOException;
+ public void sendAction(String s) throws java.io.IOException;
+}
Property changes on: trunk/clients/javer/src/javer/QueryTab.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/SimpleTextTab.form
===================================================================
--- trunk/clients/javer/src/javer/SimpleTextTab.form 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/SimpleTextTab.form 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+
+ <Layout
class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"
value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="Center"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout
class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JTextArea" name="textField">
+ <Properties>
+ <Property name="editable" type="boolean" value="false"/>
+ <Property name="lineWrap" type="boolean" value="true"/>
+ </Properties>
+ </Component>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+</Form>
Added: trunk/clients/javer/src/javer/SimpleTextTab.java
===================================================================
--- trunk/clients/javer/src/javer/SimpleTextTab.java 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/SimpleTextTab.java 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,54 @@
+/*
+ * SimpleTextTab.java
+ *
+ * Created on January 6, 2005, 2:26 PM
+ */
+
+package javer;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class SimpleTextTab extends javax.swing.JPanel implements TextTab {
+
+ /** Creates new form SimpleTextTab */
+ protected SimpleTextTab() {
+ initComponents();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ private void initComponents() {//GEN-BEGIN:initComponents
+ jScrollPane1 = new javax.swing.JScrollPane();
+ textField = new javax.swing.JTextArea();
+
+ setLayout(new java.awt.BorderLayout());
+
+ textField.setEditable(false);
+ textField.setLineWrap(true);
+ jScrollPane1.setViewportView(textField);
+
+ add(jScrollPane1, java.awt.BorderLayout.CENTER);
+
+ }//GEN-END:initComponents
+
+ public void putText(String s) {
+ textField.append(s + "\n");
+ textField.setCaretPosition(textField.getText().length() - 1);
+ }
+
+ public void setText(String s) {
+ textField.setText(s);
+ textField.setCaretPosition(textField.getText().length() - 1);
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JTextArea textField;
+ // End of variables declaration//GEN-END:variables
+
+}
Property changes on: trunk/clients/javer/src/javer/SimpleTextTab.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/TextFormatter.java
===================================================================
--- trunk/clients/javer/src/javer/TextFormatter.java 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/TextFormatter.java 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,139 @@
+/*
+ * TextFormatter.java
+ *
+ * Created on January 8, 2005, 9:45 PM
+ */
+
+package javer;
+import java.util.*;
+import java.util.regex.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class TextFormatter implements java.io.Serializable, Cloneable {
+
+ protected static Pattern parsepattern = Pattern.compile("%[^%]*%");
+ protected Vector format;
+ protected String formatstr;
+ protected Set expectedKeys;
+
+ /** Creates a new instance of TextFormatter */
+ public TextFormatter(String formatstr) {
+ this(formatstr, null);
+ }
+
+ public TextFormatter(String formatstr, Set expectedKeys) {
+ this.formatstr = formatstr;
+ this.expectedKeys = new HashSet(expectedKeys);
+ parse(formatstr);
+ }
+
+ protected void parse(String formatStr) {
+ Matcher m = parsepattern.matcher(formatStr);
+ int lastEnd = 0;
+ Vector format = new Vector();
+ Iterator it;
+ while (m.find()) {
+ if (m.start() != lastEnd) {
+ /* grab the literal text between the last replace and now */
+ String literal = formatStr.substring(lastEnd, m.start());
+ LiteralChunk c = new LiteralChunk(formatStr, lastEnd, literal);
+ format.add(c);
+ }
+ Chunk c;
+ String key = formatStr.substring(m.start() + 1, m.end() - 1);
+ lastEnd = m.end();
+ if (key.equals("")) {
+ c = new LiteralChunk(formatStr, m.start(), "%");
+ format.add(c);
+ continue;
+ }
+ if (expectedKeys != null) {
+ if (!expectedKeys.contains(key)) {
+ throw new FormatException(formatStr, m.start(),
+ "Unexpected replacement key: " + key);
+ }
+ }
+ c = new ReplaceChunk(formatStr, m.start(), key);
+ format.add(c);
+ }
+ /* grab any literal data left */
+ String remain = formatStr.substring(lastEnd);
+ if (remain.length() != 0) {
+ format.add(new LiteralChunk(formatStr, lastEnd, remain));
+ }
+ format.trimToSize();
+ this.format = format;
+ }
+
+ public String format(Map replacements) {
+ StringBuffer b = new StringBuffer();
+ Iterator it = format.iterator();
+ while(it.hasNext()) {
+ Chunk c = (Chunk) it.next();
+ b.append(c.generate(replacements));
+ }
+ return b.toString();
+ }
+
+ protected interface Chunk extends java.io.Serializable, Cloneable {
+ public String generate(Map replacements);
+ }
+
+ protected final class LiteralChunk implements Chunk {
+ String literal;
+ public String generate(Map replacements) {
+ return literal;
+ }
+
+ public LiteralChunk(String formatStr, int pos, String literal) {
+ this.literal = literal;
+ }
+ }
+
+ protected final class ReplaceChunk implements Chunk {
+ String key, formatStr;
+ int pos;
+
+ public String generate(Map replacements) {
+ String value = (String) replacements.get(key);
+ if (value == null) {
+ throw new FormatException(formatStr, pos, "Key not found: " +
key);
+ }
+ return value;
+ }
+
+ public ReplaceChunk(String formatStr, int pos, String key) {
+ this.key = key;
+ this.formatStr = formatStr;
+ this.pos = pos;
+ }
+ }
+
+ public class FormatException extends RuntimeException {
+ public FormatException(String formatstr, int pos, String errorDesc) {
+ super(errorDesc);
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ String format;
+ HashMap repl = new HashMap(args.length - 1);
+ java.io.BufferedReader pr = new java.io.BufferedReader(
+ new java.io.InputStreamReader(System.in));
+ int i;
+
+ for (i = 0; i * 2 + 1 < args.length; i++) {
+ repl.put(args[i * 2], args[i * 2 + 1]);
+ }
+ while (true) {
+ TextFormatter f;
+ format = pr.readLine();
+ f = new TextFormatter(format, repl.keySet());
+ System.out.println(f.format(repl));
+ }
+ }
+
+}
Property changes on: trunk/clients/javer/src/javer/TextFormatter.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/TextTab.java
===================================================================
--- trunk/clients/javer/src/javer/TextTab.java 2005-04-12 02:39:42 UTC (rev
670)
+++ trunk/clients/javer/src/javer/TextTab.java 2005-04-25 00:49:04 UTC (rev
671)
@@ -0,0 +1,15 @@
+/*
+ * TextTab.java
+ *
+ * Created on January 6, 2005, 12:44 AM
+ */
+
+package javer;
+
+/**
+ *
+ * @author bdonlan
+ */
+public interface TextTab {
+ public void putText(String s);
+}
Property changes on: trunk/clients/javer/src/javer/TextTab.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/ThreadRendezvous.java
===================================================================
--- trunk/clients/javer/src/javer/ThreadRendezvous.java 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/ThreadRendezvous.java 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,50 @@
+/*
+ * ThreadRendezvous.java
+ *
+ * Created on January 10, 2005, 1:42 PM
+ */
+
+package javer;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class ThreadRendezvous {
+
+ Object value = null;
+ boolean completed = false;
+
+ /** Creates a new instance of ThreadRendezvous */
+ public ThreadRendezvous() {
+ }
+
+ public synchronized void complete(Object o) {
+ if (completed) {
+ throw new IllegalStateException("Cannot complete a rendezvous
twice");
+ }
+ value = o;
+ completed = true;
+ notifyAll();
+ }
+
+ public synchronized boolean isComplete() {
+ return completed;
+ }
+
+ public synchronized Object block() throws InterruptedException {
+ return block(0, 0);
+ }
+
+ public synchronized Object block(long timeout) throws InterruptedException
{
+ return block(timeout, 0);
+ }
+
+ public synchronized Object block(long timeout, int nanos) throws
InterruptedException {
+ if (completed)
+ return value;
+ this.wait(timeout, nanos);
+ return value;
+ }
+
+}
Property changes on: trunk/clients/javer/src/javer/ThreadRendezvous.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/TimedInvoker.java
===================================================================
--- trunk/clients/javer/src/javer/TimedInvoker.java 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/TimedInvoker.java 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,37 @@
+/*
+ * TimedInvoker.java
+ *
+ * Created on January 14, 2005, 7:40PM
+ */
+
+package javer;
+import java.util.*;
+import java.io.*;
+import java.math.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+final class TimedInvoker {
+
+ static TimerThread tt = new TimerThread();
+
+ private TimedInvoker() {
+ throw new IllegalStateException("Cannot instantiate a singleton
class");
+ }
+
+ public static Object invokeAt(long absoluteTimeMillis, Runnable invokee) {
+ return tt.addTimer(absoluteTimeMillis, invokee);
+ }
+
+ public static Object invokeAfter(long deltaMillis, Runnable invokee) {
+ return tt.addTimer(System.currentTimeMillis() + deltaMillis,
+ invokee);
+ }
+
+ public static boolean unschedule(Object tag) {
+ return tt.cancelTimer(tag);
+ }
+
+}
\ No newline at end of file
Property changes on: trunk/clients/javer/src/javer/TimedInvoker.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/TimerThread.java
===================================================================
--- trunk/clients/javer/src/javer/TimerThread.java 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/TimerThread.java 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,118 @@
+/*
+ * TimerThread.java
+ *
+ * Created on January 14, 2005, 7:47 PM
+ */
+
+package javer;
+import java.util.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+class TimerThread implements Runnable {
+
+ class Timer {
+ Runnable evt;
+ long when;
+ }
+
+ Thread thread = null;
+ SortedMap queue = new TreeMap();
+
+ protected void notifyThread() {
+ synchronized (queue) {
+ if (thread == null || !thread.isAlive()) {
+ thread = new Thread(this);
+ //System.out.println("TT: spawning");
+ thread.start();
+ return;
+ }
+ //System.out.println("TT: interrupting");
+ thread.interrupt();
+ }
+ }
+
+ protected synchronized Object addTimer(long when, Runnable event) {
+ Set slot;
+ Timer te = new Timer();
+ Long oWhen = new Long(when);
+ te.evt = event;
+ te.when = when;
+ synchronized (queue) {
+ slot = (Set)queue.get(oWhen);
+ if (slot == null) {
+ slot = new LinkedHashSet();
+ }
+ slot.add(te);
+ queue.put(oWhen, slot);
+ //System.out.println("TT: add queuelen=" + queue.size());
+ //System.out.println("TT: add slotlen=" + slot.size());
+ notifyThread();
+ }
+ return te;
+ }
+
+ protected synchronized boolean cancelTimer(Object tag) {
+ Timer te = (Timer) tag;
+ Long when = new Long(te.when);
+ synchronized (queue) {
+ Set slot = (Set)queue.get(when);
+ if (slot == null)
+ return false;
+ slot.remove(te);
+ if (slot.isEmpty())
+ queue.remove(when);
+ /* We don't need to notify the thread; if this slot is next then
+ * the thread will just go back to sleep or die once it discovers
+ * the first slot time has changed.
+ */
+ return true;
+ }
+ }
+
+ public void run() {
+ if (Thread.currentThread() != thread)
+ return;
+ while (true) {
+ long nextSlot, delta, now;
+ Set slot = null;
+ now = System.currentTimeMillis();
+ synchronized (queue) {
+ Long firstkey;
+ if (queue.size() == 0) {
+ /* No work? We die. */
+ //System.out.println("TT: no work, killing thread");
+ thread = null;
+ return;
+ }
+ firstkey = (Long)queue.firstKey();
+ nextSlot = firstkey.longValue();
+ //System.out.println("TT: nxS=" + nextSlot + "\nTT: now=" +
now);
+ if (nextSlot <= now) {
+ //System.out.println("TT: pop=" + nextSlot);
+ slot = (Set) queue.remove(firstkey);
+ }
+ }
+ if (slot != null) {
+ Iterator it = slot.iterator();
+ //System.out.println("TT: slotsize=" + slot.size());
+ while (it.hasNext()) {
+ Timer te = (Timer)it.next();
+ //System.out.println("TT: invokeLater("+te.evt+")");
+ java.awt.EventQueue.invokeLater(te.evt);
+ }
+ continue;
+ }
+ delta = nextSlot - now;
+ try {
+ thread.sleep(delta);
+ } catch (InterruptedException e) {}
+ }
+ }
+
+ TimerThread() {
+ }
+}
+
Property changes on: trunk/clients/javer/src/javer/TimerThread.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/clients/javer/src/javer/UserQueryTab.java
===================================================================
--- trunk/clients/javer/src/javer/UserQueryTab.java 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/clients/javer/src/javer/UserQueryTab.java 2005-04-25 00:49:04 UTC
(rev 671)
@@ -0,0 +1,40 @@
+/*
+ * UserQueryTab.java
+ *
+ * Created on January 6, 2005, 10:39 PM
+ */
+
+package javer;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class UserQueryTab extends SimpleTextTab implements QueryTab {
+
+ String who;
+ HaverClient cli;
+
+ /** Creates a new instance of UserQueryTab */
+ public UserQueryTab(HaverClient cli, String who) {
+ super();
+ this.cli = cli;
+ this.who = who;
+ putText("--- Opening query with: " + who);
+ }
+
+ public String getUID() {
+ return who;
+ }
+
+ public void sendAction(String s) throws java.io.IOException {
+ putText("* " + cli.getUID() + " " + s);
+ cli.sendPrivateAction(who, s);
+ }
+
+ public void sendText(String s) throws java.io.IOException {
+ putText("<" + cli.getUID() + "> " + s);
+ cli.sendPrivateNormalMessage(who, s);
+ }
+
+}
Property changes on: trunk/clients/javer/src/javer/UserQueryTab.java
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: trunk/main/server/lib/Haver/Server/Base.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/Base.pm 2005-04-12 02:39:42 UTC (rev
670)
+++ trunk/main/server/lib/Haver/Server/Base.pm 2005-04-25 00:49:04 UTC (rev
671)
@@ -1,12 +1,10 @@
-# vim: set ts=4 sw=4 expandtab si ai sta tw=100:
+# vim: set ts=4 sw=4 si ai sta tw=100:
# This module is copyrighted, see end of file for details.
package Haver::Server::Base;
use Spiffy qw( -Base );
-use Spiffy qw( -XXX -dumper );
use Carp;
-our @EXPORT = qw( croak carp confess );
-our @EXPORT_BASE = qw( field );
+our @EXPORT_BASE = qw( field croak carp confess );
{
Modified: trunk/main/server/lib/Haver/Server/Listener.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/Listener.pm 2005-04-12 02:39:42 UTC
(rev 670)
+++ trunk/main/server/lib/Haver/Server/Listener.pm 2005-04-25 00:49:04 UTC
(rev 671)
@@ -1,54 +1,30 @@
-# Haver::Server::POE::Listener,
-# this creates a session that listens for connections,
-# and when something connects, it spawns
-# a Haver::Server::Connection session.
-#
-# Copyright (C) 2003 Dylan William Hardison.
-#
-# This module is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This module is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this module; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-# TODO, write POD. Soon.
package Haver::Server::Listener;
-use strict;
-use warnings;
-use Carp;
-use POE qw(
- Wheel::SocketFactory
-);
+use Haver::Server::Base '-Base';
-use Haver::Preprocessor;
+use POE;
+use POE::Wheel::SocketFactory;
use Haver::Server::Speaker;
sub create {
my $class = shift;
- # ASSERT: (@_ == 1 and ref($_[0]) eq 'HASH') or ((@_ % 2) == 0);
- my $opts = @_ == 1 ? $_[0] : { @_ };
+ my %opts = @_;
+ unless (exists $opt{acceptor}) {
+ croak "Require parameter acceptor missing";
+ }
POE::Session->create(
- package_states =>
- [
+ package_states => [
$class => [qw(
_start
_stop
socket_birth
socket_fail
listen
+ unlisten
shutdown
)],
],
- heap => $opts,
+ heap => {},
);
}
@@ -56,36 +32,34 @@
my ($kernel, $heap) = @_[KERNEL, HEAP];
- # DEBUG(session): "Listener starts.";
- $heap->{wheels} = {};
- $heap->{info} = {};
- $heap->{kids} = {};
+ $heap->{listeners} = {};
+ $heap->{children} = {};
+ $heap->{names} = {};
$kernel->alias_set('Listener');
}
sub _stop {
my ($kernel, $heap) = @_[KERNEL,HEAP];
- # DEBUG(session): "Listener stops.";
}
sub _child {
my ($kernel, $heap, $type, $kid) = @_[KERNEL, HEAP, ARG0, ARG1];
if ($type eq 'create' or $type eq 'gain') {
- $heap->{kids}{$kid->ID} = 1;
+ $heap->{children}{$kid->ID} = 1;
} elsif ($type eq 'lose') {
- delete $heap->{kids}{$kid->ID};
+ delete $heap->{children}{$kid->ID};
} else {
die "I don't know how I got here!\n";
}
}
-# iface = {
-# host => string # to $bindto . ':' . $port or $port if $bindto is undef.
-# bindto => domain_name | IPv4_addr
-# port => service_name | port_number
-# }
+# $iface = {
+# name => 'example.com',
+# port => 7070,
+# addr => "IP address of interface bind to",
+# }
sub listen {
my ($kernel, $heap, $iface) = @_[KERNEL, HEAP, ARG0, ARG1];
@@ -93,47 +67,56 @@
my $wheel = POE::Wheel::SocketFactory->new(
BindPort => $iface->{port},
+ BindAddress => $iface->{addr},
Reuse => 1,
SuccessEvent => 'socket_birth',
FailureEvent => 'socket_fail',
);
- $heap->{wheels}{$wheel->ID} = $wheel;
- $heap->{info}{$wheel->ID} = $iface;
+ $heap->{listeners}{$wheel->ID} = {
+ wheel => $wheel,
+ iface => $iface,
+ };
+ $heap->{names}{ $iface->{name} } = $wheel->ID;
}
sub unlisten {
- my ($kernel, $heap, $iface
+ my ($kernel, $heap, $name) = @_[KERNEL, HEAP, ARG0];
+ my $wid = delete $heap->{names}{ $iface->{name} }
+ unless ($wid) {
+ warn "$name is not a valid listener name.";
+ }
+
+ delete $heap->{listeners}{$wid}
+ or warn "Unable to delete wheel with id $wid (name: $name)";
}
sub socket_birth {
my ($kernel, $heap, $socket, $address, $port, $wid) =
@_[KERNEL, HEAP, ARG0, ARG1, ARG2, ARG3];
- my $info = $heap->{info}{$wid};
-
- create Haver::Server::Speaker {
+ my $info = $heap->{listeners}{$wid}{iface};
+
+ $heap->{acceptor}->(
sock => $socket,
address => Socket::inet_ntoa($address),
port => $port,
iface => $info,
- };
+ );
+
}
sub socket_fail {
my ($kernel, $heap, $operation, $errnum, $errstr, $wheel_id) =
@_[KERNEL, HEAP, ARG0..ARG3];
- delete $heap->{info}{$wheel_id};
- delete $heap->{wheels}{$wheel_id};
+ delete $heap->{listeners}{$wheel_id}{wheel};
- $kernel->post('Logger', 'error', "Operation '$operation' failed:
$errstr ($errnum)");
+ warn "Operation '$operation' failed: $errstr ($errnum)";
}
sub shutdown {
my ($kernel, $heap) = @_[KERNEL, HEAP];
$kernel->alias_remove('Listener');
- foreach my $kid (keys %{ $heap->{kids} }) {
+ foreach my $kid (keys %{ $heap->{children} }) {
$kernel->post($kid, 'shutdown');
}
%$heap = ();
}
-
-1;