Removed lots of dead code
This commit is contained in:
Binary file not shown.
@@ -1,18 +0,0 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
|
||||
@@ -1,17 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="[Linux] Run MS" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/run-ms.sh" />
|
||||
<option name="SCRIPT_OPTIONS" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="/bin/bash" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="false" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="true" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,11 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="[Windows] Run MS" type="BatchConfigurationType" factoryName="Batch">
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<module name="" />
|
||||
<option name="SCRIPT_NAME" value="./run-ms.bat" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"DatabaseInformation": {
|
||||
"database_name": "global",
|
||||
"database_username": "root",
|
||||
"database_password": "",
|
||||
"database_host": "127.0.0.1",
|
||||
"database_port": "3306"
|
||||
},
|
||||
|
||||
"WorldTechnicalInformation": {
|
||||
"world_limit": "10",
|
||||
"worldhop_delay": "20000"
|
||||
},
|
||||
"secret_key": "2009scape_development"
|
||||
}
|
||||
Vendored
-287
@@ -1,287 +0,0 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Apache Maven Wrapper startup batch script, version 3.1.1
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /usr/local/etc/mavenrc ] ; then
|
||||
. /usr/local/etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME
|
||||
else
|
||||
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`\\unset -f command; \\command -v java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
printf '%s' "$(cd "$basedir"; pwd)"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=$(find_maven_basedir "$(dirname $0)")
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
||||
else
|
||||
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
||||
fi
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $wrapperUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if $cygwin; then
|
||||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
QUIET="--quiet"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
QUIET=""
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath"
|
||||
else
|
||||
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath"
|
||||
fi
|
||||
[ $? -eq 0 ] || rm -f "$wrapperJarPath"
|
||||
elif command -v curl > /dev/null; then
|
||||
QUIET="--silent"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
QUIET=""
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L
|
||||
else
|
||||
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L
|
||||
fi
|
||||
[ $? -eq 0 ] || rm -f "$wrapperJarPath"
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaSource=`cygpath --path --windows "$javaSource"`
|
||||
javaClass=`cygpath --path --windows "$javaClass"`
|
||||
fi
|
||||
if [ -e "$javaSource" ]; then
|
||||
if [ ! -e "$javaClass" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaSource")
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
$MAVEN_DEBUG_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
||||
Vendored
-187
@@ -1,187 +0,0 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Apache Maven Wrapper startup batch script, version 3.1.1
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
|
||||
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
||||
|
||||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %WRAPPER_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% ^
|
||||
%JVM_CONFIG_MAVEN_PROPS% ^
|
||||
%MAVEN_OPTS% ^
|
||||
%MAVEN_DEBUG_OPTS% ^
|
||||
-classpath %WRAPPER_JAR% ^
|
||||
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
|
||||
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
||||
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%"=="on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
|
||||
|
||||
cmd /C exit /B %ERROR_CODE%
|
||||
@@ -1,153 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.rs09</groupId>
|
||||
<artifactId>managementserver</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<properties>
|
||||
<project.mainClassName>ms.Management</project.mainClassName>
|
||||
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
|
||||
<kotlin.version>1.6.21</kotlin.version>
|
||||
<kotlin.comipler.jvmTarget>1.6</kotlin.comipler.jvmTarget>
|
||||
<junit.version>5.7.0</junit.version>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.json-simple</groupId>
|
||||
<artifactId>json-simple</artifactId>
|
||||
<version>1.1.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ajalt.mordant</groupId>
|
||||
<artifactId>mordant-jvm</artifactId>
|
||||
<version>2.0.0-beta6</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.21</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<archive>
|
||||
<manifest><mainClass>${project.mainClassName}</mainClass></manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
|
||||
<sourceDir>${project.basedir}/src/main/java</sourceDir>
|
||||
</sourceDirs>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<goals> <goal>test-compile</goal> </goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
|
||||
</sourceDirs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<useIncrementalCompilation>false</useIncrementalCompilation>
|
||||
</configuration>
|
||||
<executions>
|
||||
<!-- Replacing default-compile as it is treated specially by maven -->
|
||||
<execution>
|
||||
<id>default-compile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<!-- Replacing default-testCompile as it is treated specially by maven -->
|
||||
<execution>
|
||||
<id>default-testCompile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>2.22.0</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,197 +0,0 @@
|
||||
package ms;
|
||||
|
||||
import ms.net.NioReactor;
|
||||
import ms.net.packet.IoBuffer;
|
||||
import ms.net.packet.PacketHeader;
|
||||
import ms.net.packet.WorldPacketRepository;
|
||||
import ms.system.ShutdownSequence;
|
||||
import ms.system.mysql.SQLManager;
|
||||
import ms.system.util.Command;
|
||||
import ms.system.util.ManagementConfigParser;
|
||||
import ms.world.GameServer;
|
||||
import ms.world.PlayerSession;
|
||||
import ms.world.WorldDatabase;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* The main class.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class Management {
|
||||
|
||||
/**
|
||||
* If the shutdown hook is active.
|
||||
*/
|
||||
public static boolean active = true;
|
||||
|
||||
/**
|
||||
* The commands.
|
||||
*/
|
||||
private static final Command[] COMMANDS = {
|
||||
new Command("-commands", "Print a list of all commands.") {
|
||||
@Override
|
||||
public void run(String...args) {
|
||||
for (Command c : COMMANDS) {
|
||||
System.out.println("Command " + c.getName() + ": " + c.getInfo());
|
||||
}
|
||||
}
|
||||
},
|
||||
new Command("-s", "Safely shuts down the server.") {
|
||||
@Override
|
||||
public void run(String...args) {
|
||||
System.out.println("Shutting down Management server...");
|
||||
ShutdownSequence.shutdown();
|
||||
}
|
||||
},
|
||||
new Command("-debug", "Debug world info.") {
|
||||
@Override
|
||||
public void run(String...args) {
|
||||
System.out.println("---------------------------------------------");
|
||||
for (GameServer server : WorldDatabase.getWorlds()) {
|
||||
if (server != null) {
|
||||
System.out.println("World [id=" + server.getInfo().getWorldId() + ", IP=" + server.getInfo().getAddress() + ", country=" + server.getInfo().getCountry() + ", members=" + server.getInfo().isMembers() + ", players=" + server.getPlayers().size() + ", active=" + server.isActive() + "].");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new Command("-pinfo", "Debugs player information (usage: -pinfo emperor).") {
|
||||
@Override
|
||||
public void run(String...args) {
|
||||
String name = args[1];
|
||||
PlayerSession player = WorldDatabase.getPlayer(name);
|
||||
if (player == null) {
|
||||
System.out.println("Player " + name + " was not registered!");
|
||||
return;
|
||||
}
|
||||
System.out.println("Player [name=" + name + ", world=" + player.getWorldId() + ", active=" + player.isActive() + "].");
|
||||
}
|
||||
},
|
||||
new Command("-update", "Calls an update on all the game servers (-update -1 to cancel).") {
|
||||
@Override
|
||||
public void run(String...args) {
|
||||
int ticks = Integer.parseInt(args[1]);
|
||||
for (GameServer server : WorldDatabase.getWorlds()) {
|
||||
if (server != null && server.isActive()) {
|
||||
WorldPacketRepository.sendUpdate(server, ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new Command("-reloadconfig", "Reloads the configurations of all worlds.") {
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
for (GameServer server : WorldDatabase.getWorlds()) {
|
||||
if(server == null) {
|
||||
continue;
|
||||
}
|
||||
WorldPacketRepository.sendConfigReload(server);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
new Command("-rlcache", "Reloads launcher/client resource cache") {
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
System.out.println("Reloaded resource cache!");
|
||||
}
|
||||
},
|
||||
|
||||
new Command("-kick", "Kicks a player from the MS (not ingame).") {
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
String name = args[1];
|
||||
PlayerSession player = WorldDatabase.getPlayer(name);
|
||||
if (player == null) {
|
||||
System.out.println("Player " + name + " was not registered!");
|
||||
return;
|
||||
}
|
||||
player.getWorld().getPlayers().remove(name);
|
||||
player.setWorldId(0);
|
||||
System.out.println("Kicked player " + name + "!");
|
||||
}
|
||||
},
|
||||
|
||||
new Command("-say", "Send a message to all worlds") {
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
String message = String.join(" ", args);
|
||||
message = message.substring(4);
|
||||
for(GameServer server : WorldDatabase.getWorlds()){
|
||||
if(server == null) continue;
|
||||
String finalMessage = message;
|
||||
server.getPlayers().forEach((String uname, PlayerSession p) -> {
|
||||
IoBuffer buffer = new IoBuffer(5, PacketHeader.BYTE);
|
||||
buffer.putString(p.getUsername());
|
||||
buffer.putString("Server");
|
||||
buffer.put(2);
|
||||
buffer.put(2);
|
||||
buffer.putString(finalMessage);
|
||||
p.getWorld().getSession().write(buffer);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The main method.
|
||||
* @param args The arguments cast on runtime.
|
||||
* @throws Throwable When an exception occurs.
|
||||
*/
|
||||
public static void main(String...args) throws Throwable {
|
||||
if (!isLocallyHosted(ServerConstants.HOST_ADDRESS)) {
|
||||
System.err.println("WARNING: Configure host address in server constants!");
|
||||
}
|
||||
System.out.println("-------- 530 Management server --------");
|
||||
System.out.println("Starting up...");
|
||||
new ManagementConfigParser("managementprops" + File.separator + "properties.json");
|
||||
SQLManager.init();
|
||||
//NioReactor.configure(ServerConstants.PORT).start();
|
||||
NioReactor.configure(5555).start();
|
||||
Runtime.getRuntime().addShutdownHook(new ShutdownSequence());
|
||||
System.out.println("Status: ready.");
|
||||
System.out.println("Use -commands for a list of commands!");
|
||||
Scanner s = new Scanner(new InputStreamReader(System.in, StandardCharsets.UTF_8));
|
||||
while (s.hasNext()) {
|
||||
try {
|
||||
String command = s.nextLine();
|
||||
if (!command.startsWith("-")) {
|
||||
continue;
|
||||
}
|
||||
String[] arguments = command.split(" ");
|
||||
command = arguments[0];
|
||||
for (Command c : COMMANDS) {
|
||||
if (c.getName().equals(command)) {
|
||||
System.out.println("Handling command \"" + command + "\"!");
|
||||
c.run(arguments);
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
s.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the Management server is locally hosted.
|
||||
* @return {@code True} if so.
|
||||
* @throws IOException When an I/O exception occurs.
|
||||
*/
|
||||
private static boolean isLocallyHosted(String ip) throws IOException {
|
||||
InetAddress address = InetAddress.getByName(ip);
|
||||
if (address.isAnyLocalAddress() || address.isLoopbackAddress()) {
|
||||
return true;
|
||||
}
|
||||
return NetworkInterface.getByInetAddress(address) != null;
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package ms;
|
||||
|
||||
import ms.system.OperatingSystem;
|
||||
|
||||
/**
|
||||
* Holds constants for the management server.
|
||||
* @author v4rg
|
||||
*
|
||||
*/
|
||||
public final class ServerConstants {
|
||||
|
||||
/**
|
||||
* The maximum amount of worlds.
|
||||
*/
|
||||
public static final int WORLD_LIMIT = 10;
|
||||
|
||||
/**
|
||||
* The world switching delay in milliseconds.
|
||||
*/
|
||||
public static final long WORLD_SWITCH_DELAY = 20_000L;
|
||||
|
||||
/**
|
||||
* The address of the Management server.
|
||||
*/
|
||||
public static final String HOST_ADDRESS = "127.0.0.1";
|
||||
|
||||
/**
|
||||
* The operating system of the management server
|
||||
*/
|
||||
public static final OperatingSystem OS = System.getProperty("os.name").toUpperCase().contains("WIN") ? OperatingSystem.WINDOWS : OperatingSystem.UNIX;
|
||||
|
||||
/**
|
||||
* Stops from instantiating.
|
||||
*/
|
||||
private ServerConstants() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes a path to a specified operating system
|
||||
* @param operatingSystem The os type.
|
||||
* @param path The path.
|
||||
* @return The fixed path.
|
||||
*/
|
||||
public static String fixPath(OperatingSystem operatingSystem, String path) {
|
||||
if (operatingSystem == null)
|
||||
operatingSystem = OS;
|
||||
return operatingSystem == OperatingSystem.WINDOWS ? path.replace("/","\\") : path.replace("\\","/");
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package ms.net;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Used for producing I/O events.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public interface EventProducer {
|
||||
|
||||
/**
|
||||
* Produces a new read event.
|
||||
* @param session The session.
|
||||
* @param buffer The buffer to read.
|
||||
* @return The read event handler.
|
||||
*/
|
||||
IoReadEvent produceReader(IoSession session, ByteBuffer buffer);
|
||||
|
||||
/**
|
||||
* Produces a new writing event.
|
||||
* @param session The session.
|
||||
* @param context The context.
|
||||
* @return The write event handler.
|
||||
*/
|
||||
IoWriteEvent produceWriter(IoSession session, Object context);
|
||||
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
package ms.net;
|
||||
|
||||
import ms.world.WorldDatabase;
|
||||
import ms09.MSLogger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
/**
|
||||
* I/O event handling.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class IoEventHandler {
|
||||
|
||||
/**
|
||||
* The executor service.
|
||||
*/
|
||||
private final ExecutorService service;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code IoEventHandler}.
|
||||
* @param service The executor service used for handling events.
|
||||
*/
|
||||
public IoEventHandler(ExecutorService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when making a new connection.
|
||||
* @param key The selection key.
|
||||
*/
|
||||
public void connect(SelectionKey key) {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for accepting a new connection.
|
||||
* @param key The selection key.
|
||||
* @param selector The selector.
|
||||
* @throws IOException When an I/O exception occurs.
|
||||
*/
|
||||
public void accept(SelectionKey key, Selector selector) throws IOException {
|
||||
SocketChannel sc = ((ServerSocketChannel) key.channel()).accept();
|
||||
sc.configureBlocking(false);
|
||||
sc.socket().setTcpNoDelay(true);
|
||||
sc.register(selector, SelectionKey.OP_READ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the incoming packet data.
|
||||
* @param key The selection key.
|
||||
* @throws IOException When an I/O exception occurs.
|
||||
*/
|
||||
public void read(SelectionKey key) throws IOException {
|
||||
ReadableByteChannel channel = (ReadableByteChannel) key.channel();
|
||||
ByteBuffer buffer = ByteBuffer.allocate(100_000);
|
||||
IoSession session = (IoSession) key.attachment();
|
||||
if (channel.read(buffer) == -1) {
|
||||
if(session == null){
|
||||
key.cancel();
|
||||
return;
|
||||
}
|
||||
if(session.getGameServer() != null){
|
||||
WorldDatabase.unRegister(session.getGameServer());
|
||||
}
|
||||
session.disconnect();
|
||||
key.cancel();
|
||||
return;
|
||||
}
|
||||
buffer.flip();
|
||||
if (session == null) {
|
||||
key.attach(session = new IoSession(key, service));
|
||||
}
|
||||
service.execute(session.getProducer().produceReader(session, buffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the outgoing packet data.
|
||||
* @param key The selection key.
|
||||
*/
|
||||
public void write(SelectionKey key) {
|
||||
IoSession session = (IoSession) key.attachment();
|
||||
if(session != null) {
|
||||
key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
|
||||
session.write();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects a connection.
|
||||
* @param key The selection key.
|
||||
* @param t The occurred exception (if any).
|
||||
*/
|
||||
public void disconnect(SelectionKey key, Throwable t) {
|
||||
try {
|
||||
IoSession session = (IoSession) key.attachment();
|
||||
String cause = "" + t;
|
||||
if (t != null && !(t instanceof ClosedChannelException || cause.contains("De externe host") || cause.contains("De software op uw") || cause.contains("An established connection was aborted") || cause.contains("An existing connection") || cause.contains("AsynchronousClose"))) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
if (session != null) {
|
||||
session.disconnect();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package ms.net;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Handles a reading event.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public abstract class IoReadEvent implements Runnable {
|
||||
|
||||
/**
|
||||
* The I/O session.
|
||||
*/
|
||||
private final IoSession session;
|
||||
|
||||
/**
|
||||
* The buffer.
|
||||
*/
|
||||
private ByteBuffer buffer;
|
||||
|
||||
/**
|
||||
* If the queued reading buffer was used (debugging purposes).
|
||||
*/
|
||||
protected boolean usedQueuedBuffer;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code IoReadEvent}.
|
||||
* @param session The session.
|
||||
* @param buffer The buffer to read from.
|
||||
*/
|
||||
public IoReadEvent(IoSession session, ByteBuffer buffer) {
|
||||
this.session = session;
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (session.getReadingQueue() != null) {
|
||||
buffer = session.getReadingQueue().put(buffer);
|
||||
buffer.flip();
|
||||
session.setReadingQueue(null);
|
||||
usedQueuedBuffer = true;
|
||||
}
|
||||
read(session, buffer);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
session.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues the buffer until more data has been received.
|
||||
* @param data The data that has been read already.
|
||||
*/
|
||||
public void queueBuffer(int...data) {
|
||||
ByteBuffer queue = ByteBuffer.allocate(data.length + buffer.remaining() + 100_000);
|
||||
for (int value : data) {
|
||||
queue.put((byte) value);
|
||||
}
|
||||
queue.put(buffer);
|
||||
session.setReadingQueue(queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the data from the buffer.
|
||||
* @param session The session.
|
||||
* @param buffer The buffer to read from.
|
||||
*/
|
||||
public abstract void read(IoSession session, ByteBuffer buffer);
|
||||
|
||||
}
|
||||
@@ -1,354 +0,0 @@
|
||||
package ms.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import ms.ServerConstants;
|
||||
import ms.net.producer.HSEventProducer;
|
||||
import ms.world.GameServer;
|
||||
|
||||
/**
|
||||
* Represents a connected I/O session.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public class IoSession {
|
||||
|
||||
/**
|
||||
* The handshake event producer.
|
||||
*/
|
||||
private static final EventProducer HANDSHAKE_PRODUCER = new HSEventProducer();
|
||||
|
||||
/**
|
||||
* The selection key.
|
||||
*/
|
||||
private final SelectionKey key;
|
||||
|
||||
/**
|
||||
* The executor service.
|
||||
*/
|
||||
private final ExecutorService service;
|
||||
|
||||
/**
|
||||
* The event producer.
|
||||
*/
|
||||
private EventProducer producer = HANDSHAKE_PRODUCER;
|
||||
|
||||
/**
|
||||
* The currently queued writing data.
|
||||
*/
|
||||
private List<ByteBuffer> writingQueue = new ArrayList<>(20);
|
||||
|
||||
/**
|
||||
* The currently queued reading data.
|
||||
*/
|
||||
private ByteBuffer readingQueue;
|
||||
|
||||
/**
|
||||
* The writing lock.
|
||||
*/
|
||||
private final Lock writingLock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* The name hash.
|
||||
*/
|
||||
private int nameHash;
|
||||
|
||||
/**
|
||||
* The server key.
|
||||
*/
|
||||
private long serverKey;
|
||||
|
||||
/**
|
||||
* The JS-5 encryption value.
|
||||
*/
|
||||
private int js5Encryption;
|
||||
|
||||
/**
|
||||
* If the session is active.
|
||||
*/
|
||||
private boolean active = true;
|
||||
|
||||
/**
|
||||
* The last ping time stamp.
|
||||
*/
|
||||
private long lastPing;
|
||||
|
||||
/**
|
||||
* The address.
|
||||
*/
|
||||
private final String address;
|
||||
|
||||
/**
|
||||
* The game server object for this session.
|
||||
*/
|
||||
private GameServer gameServer;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code IoSession}.
|
||||
* @param key The selection key.
|
||||
* @param service The executor service.
|
||||
*/
|
||||
public IoSession(SelectionKey key, ExecutorService service) {
|
||||
this.key = key;
|
||||
this.service = service;
|
||||
String address = getRemoteAddress().replaceAll("/", "").split(":")[0];
|
||||
if (address.equals("127.0.0.1")) {
|
||||
address = ServerConstants.HOST_ADDRESS;
|
||||
}
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires a write event created using the current event producer.
|
||||
* @param context The event context.
|
||||
*/
|
||||
public void write(Object context) {
|
||||
write(context, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires a write event created using the current event producer.
|
||||
* @param context The event context.
|
||||
* @param instant If the event should be instantly executed on this thread.
|
||||
*/
|
||||
public void write(Object context, boolean instant) {
|
||||
if (context == null) {
|
||||
throw new IllegalStateException("Invalid writing context!");
|
||||
}
|
||||
if (instant) {
|
||||
producer.produceWriter(this, context).run();
|
||||
return;
|
||||
}
|
||||
service.execute(producer.produceWriter(this, context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the packet data (without write event encoding).
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
public void queue(ByteBuffer buffer) {
|
||||
try {
|
||||
if(writingLock.tryLock(1000L, TimeUnit.MILLISECONDS)){
|
||||
writingQueue.add(buffer);
|
||||
writingLock.unlock();
|
||||
write();
|
||||
}
|
||||
} catch (Exception e){
|
||||
e.printStackTrace();
|
||||
writingLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the writing of all buffers in the queue.
|
||||
*/
|
||||
public void write() {
|
||||
|
||||
if (!key.isValid()) {
|
||||
disconnect();
|
||||
return;
|
||||
}
|
||||
writingLock.lock();
|
||||
SocketChannel channel = (SocketChannel) key.channel();
|
||||
try {
|
||||
while (!writingQueue.isEmpty()) {
|
||||
ByteBuffer buffer = writingQueue.get(0);
|
||||
channel.write(buffer);
|
||||
if (buffer.hasRemaining()) {
|
||||
key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
|
||||
break;
|
||||
}
|
||||
writingQueue.remove(0);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
disconnect();
|
||||
} finally {
|
||||
writingLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the session.
|
||||
*/
|
||||
public void disconnect() {
|
||||
try {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
active = false;
|
||||
key.cancel();
|
||||
SocketChannel channel = (SocketChannel) key.channel();
|
||||
channel.socket().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the IP-address (without the port).
|
||||
* @return The address.
|
||||
*/
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the remote address of this session.
|
||||
* @return The remote address, as a String.
|
||||
*/
|
||||
public String getRemoteAddress() {
|
||||
try {
|
||||
return ((SocketChannel) key.channel()).getRemoteAddress().toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current event producer.
|
||||
* @return The producer.
|
||||
*/
|
||||
public EventProducer getProducer() {
|
||||
return producer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event producer.
|
||||
* @param producer The producer to set.
|
||||
*/
|
||||
public void setProducer(EventProducer producer) {
|
||||
this.producer = producer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the queued reading data.
|
||||
* @return The readingQueue.
|
||||
*/
|
||||
public ByteBuffer getReadingQueue() {
|
||||
synchronized (this) {
|
||||
return readingQueue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues reading data.
|
||||
* @param readingQueue The readingQueue to set.
|
||||
*/
|
||||
public void setReadingQueue(ByteBuffer readingQueue) {
|
||||
synchronized (this) {
|
||||
this.readingQueue = readingQueue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the writing lock.
|
||||
* @return The writing lock.
|
||||
*/
|
||||
public Lock getWritingLock() {
|
||||
return writingLock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the selection key.
|
||||
* @return The selection key.
|
||||
*/
|
||||
public SelectionKey getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The active.
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The js5Encryption.
|
||||
*/
|
||||
public int getJs5Encryption() {
|
||||
return js5Encryption;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param js5Encryption The js5Encryption to set.
|
||||
*/
|
||||
public void setJs5Encryption(int js5Encryption) {
|
||||
this.js5Encryption = js5Encryption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lastPing.
|
||||
* @return The lastPing.
|
||||
*/
|
||||
public long getLastPing() {
|
||||
return lastPing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lastPing.
|
||||
* @param lastPing The lastPing to set.
|
||||
*/
|
||||
public void setLastPing(long lastPing) {
|
||||
this.lastPing = lastPing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nameHash.
|
||||
* @return The nameHash.
|
||||
*/
|
||||
public int getNameHash() {
|
||||
return nameHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nameHash.
|
||||
* @param nameHash The nameHash to set.
|
||||
*/
|
||||
public void setNameHash(int nameHash) {
|
||||
this.nameHash = nameHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the serverKey.
|
||||
* @return The serverKey.
|
||||
*/
|
||||
public long getServerKey() {
|
||||
return serverKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the serverKey.
|
||||
* @param serverKey The serverKey to set.
|
||||
*/
|
||||
public void setServerKey(long serverKey) {
|
||||
this.serverKey = serverKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the gameServer value.
|
||||
* @return The gameServer.
|
||||
*/
|
||||
public GameServer getGameServer() {
|
||||
return gameServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the gameServer value.
|
||||
* @param gameServer The gameServer to set.
|
||||
*/
|
||||
public void setGameServer(GameServer gameServer) {
|
||||
this.gameServer = gameServer;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package ms.net;
|
||||
|
||||
import java.nio.channels.CancelledKeyException;
|
||||
|
||||
/**
|
||||
* Handles a writing event.
|
||||
* @author Emperor
|
||||
*/
|
||||
public abstract class IoWriteEvent implements Runnable {
|
||||
|
||||
/**
|
||||
* The I/O session.
|
||||
*/
|
||||
private final IoSession session;
|
||||
|
||||
/**
|
||||
* The buffer.
|
||||
*/
|
||||
private final Object context;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code IoWriteEvent}.
|
||||
* @param session The session.
|
||||
* @param context The write event context.
|
||||
*/
|
||||
public IoWriteEvent(IoSession session, Object context) {
|
||||
this.session = session;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
write(session, context);
|
||||
} catch (Throwable t) {
|
||||
if (!(t instanceof CancelledKeyException)) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
session.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the data.
|
||||
* @param session The session.
|
||||
* @param context The write event context.
|
||||
*/
|
||||
public abstract void write(IoSession session, Object context);
|
||||
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
package ms.net;
|
||||
|
||||
import ms.Management;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Handles (NIO-based) networking events using the reactor pattern.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class NioReactor implements Runnable {
|
||||
|
||||
/**
|
||||
* The executor service.
|
||||
*/
|
||||
private final ExecutorService service;
|
||||
|
||||
/**
|
||||
* The selector
|
||||
*/
|
||||
private Selector selector;
|
||||
|
||||
/**
|
||||
* The socket channel.
|
||||
*/
|
||||
private ServerSocketChannel channel;
|
||||
|
||||
/**
|
||||
* The I/O event handling instance.
|
||||
*/
|
||||
private final IoEventHandler eventHandler;
|
||||
|
||||
/**
|
||||
* If the reactor is running.
|
||||
*/
|
||||
private boolean running;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code NioReactor}.
|
||||
* @param poolSize The pool size.
|
||||
*/
|
||||
private NioReactor(int poolSize) {
|
||||
this.service = Executors.newSingleThreadScheduledExecutor();
|
||||
this.eventHandler = new IoEventHandler(Executors.newFixedThreadPool(poolSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and configures a new {@code NioReactor} with a pool size of 1.
|
||||
* @param port The port.
|
||||
* @return The {@code NioReactor} {@code Object}.
|
||||
* @throws IOException When an I/O exception occurs.
|
||||
*/
|
||||
public static NioReactor configure(int port) throws IOException {
|
||||
return configure(port, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and configures a new {@code NioReactor}.
|
||||
* @param port The port.
|
||||
* @param poolSize The amount of threads in the thread pool.
|
||||
* @return The {@code NioReactor} {@code Object}.
|
||||
* @throws IOException When an I/O exception occurs.
|
||||
*/
|
||||
public static NioReactor configure(int port, int poolSize) throws IOException {
|
||||
NioReactor reactor = new NioReactor(poolSize);
|
||||
reactor.channel = ServerSocketChannel.open();
|
||||
reactor.selector = Selector.open();
|
||||
reactor.channel.bind(new InetSocketAddress(port));
|
||||
reactor.channel.configureBlocking(false);
|
||||
reactor.channel.register(reactor.selector, SelectionKey.OP_ACCEPT);
|
||||
return reactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the reactor.
|
||||
*/
|
||||
public void start() {
|
||||
running = true;
|
||||
service.execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (running && Management.active) {
|
||||
try {
|
||||
if(selector.select() > 0){
|
||||
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
|
||||
while (keys.hasNext()) {
|
||||
SelectionKey key = keys.next();
|
||||
keys.remove();
|
||||
try {
|
||||
if(key == null) continue;
|
||||
if (!key.isValid() || !key.channel().isOpen()) {
|
||||
key.cancel();
|
||||
continue;
|
||||
}
|
||||
if (key.isAcceptable()) {
|
||||
eventHandler.accept(key, selector);
|
||||
}
|
||||
if (key.isReadable()) {
|
||||
eventHandler.read(key);
|
||||
}
|
||||
else if (key.isWritable()) {
|
||||
eventHandler.write(key);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
eventHandler.disconnect(key, t);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println("SLEEPING");
|
||||
Thread.sleep(200);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates the reactor (once it's done processing current I/O events).
|
||||
*/
|
||||
public void terminate() {
|
||||
running = false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
package ms.net.event;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.Locale;
|
||||
|
||||
import ms.Management;
|
||||
import ms.net.IoReadEvent;
|
||||
import ms.net.IoSession;
|
||||
import ms.net.packet.IoBuffer;
|
||||
import ms.system.mysql.SQLManager;
|
||||
import ms.system.util.ManagementConstants;
|
||||
import ms.world.PlayerSession;
|
||||
import ms.world.WorldDatabase;
|
||||
import ms.system.util.ByteBufferUtils;
|
||||
|
||||
/**
|
||||
* Handles handshake read events.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class HSReadEvent extends IoReadEvent {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HSReadEvent}.
|
||||
* @param session The session.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
public HSReadEvent(IoSession session, ByteBuffer buffer) {
|
||||
super(session, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(IoSession session, ByteBuffer buffer) {
|
||||
int opcode = buffer.get() & 0xFF;
|
||||
switch (opcode) {
|
||||
case 88:
|
||||
String password = ByteBufferUtils.getString(buffer);
|
||||
if (!password.equals(ManagementConstants.getSECRET_KEY())) {
|
||||
System.out.println("Password mismatch (attempt=" + password + ")!");
|
||||
session.disconnect();
|
||||
break;
|
||||
}
|
||||
session.write(opcode);
|
||||
break;
|
||||
case 255: // World list
|
||||
int updateStamp = buffer.getInt();
|
||||
WorldDatabase.sendUpdate(session, updateStamp);
|
||||
break;
|
||||
case 35:
|
||||
IoBuffer buf = new IoBuffer();
|
||||
String username = ByteBufferUtils.getString(buffer).toLowerCase();
|
||||
password = ByteBufferUtils.getString(buffer);
|
||||
if (!password.equals(ManagementConstants.getSECRET_KEY())){
|
||||
System.out.println("Password mismatch (attempt=" + password + ")!");
|
||||
buf.put(1);
|
||||
ByteBuffer buff = buf.toByteBuffer();
|
||||
buff.flip();
|
||||
session.queue(buff);
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerSession player = WorldDatabase.getPlayer(username);
|
||||
if (player == null) {
|
||||
System.out.println("Player " + username + " was not registered!");
|
||||
buf.put(2);
|
||||
ByteBuffer buff = buf.toByteBuffer();
|
||||
buff.flip();
|
||||
session.queue(buff);
|
||||
return;
|
||||
}
|
||||
buf.put(0);
|
||||
ByteBuffer buff = buf.toByteBuffer();
|
||||
buff.flip();
|
||||
session.queue(buff);
|
||||
player.getWorld().getPlayers().remove(username);
|
||||
player.setWorldId(0);
|
||||
break;
|
||||
case 36:
|
||||
buf = new IoBuffer();
|
||||
username = ByteBufferUtils.getString(buffer).toLowerCase();
|
||||
password = ByteBufferUtils.getString(buffer);
|
||||
int credits = buffer.getInt();
|
||||
if (!password.equals(ManagementConstants.getSECRET_KEY())){
|
||||
System.out.println("Password mismatch (attempt=" + password + ")!");
|
||||
buf.put(1);
|
||||
buff = buf.toByteBuffer();
|
||||
buff.flip();
|
||||
session.queue(buff);
|
||||
return;
|
||||
}
|
||||
try (Connection con = SQLManager.getConnection()) {
|
||||
Statement stmt = con.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT credits FROM members WHERE username = \"" + username + "\";");
|
||||
int original;
|
||||
if (rs.next()) original = rs.getInt(1);
|
||||
else {
|
||||
buf.put(2);
|
||||
buff = buf.toByteBuffer();
|
||||
buff.flip();
|
||||
session.queue(buff);
|
||||
return;
|
||||
}
|
||||
stmt.execute("UPDATE members SET credits = " + (original + credits) + " WHERE username = \"" + username + "\";");
|
||||
buf.put(0);
|
||||
buf.putInt(original + credits);
|
||||
buff = buf.toByteBuffer();
|
||||
buff.flip();
|
||||
session.queue(buff);
|
||||
} catch (Exception e) {
|
||||
buf.put(3);
|
||||
buf.putString(e.toString());
|
||||
buff = buf.toByteBuffer();
|
||||
buff.flip();
|
||||
session.queue(buff);
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("Unhandled handshake opcode: " + opcode + ".");
|
||||
session.disconnect();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package ms.net.event;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import ms.net.IoSession;
|
||||
import ms.net.IoWriteEvent;
|
||||
import ms.net.producer.RegistryEventProducer;
|
||||
|
||||
/**
|
||||
* Handles Handshake write events.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class HSWriteEvent extends IoWriteEvent {
|
||||
|
||||
/**
|
||||
* The login event producer.
|
||||
*/
|
||||
private static final RegistryEventProducer REGISTRY_PRODUCER = new RegistryEventProducer();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HSWriteEvent} {@code Object}.
|
||||
* @param session The session.
|
||||
* @param context The context.
|
||||
*/
|
||||
public HSWriteEvent(IoSession session, Object context) {
|
||||
super(session, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoSession session, Object context) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(9);
|
||||
buffer.put((byte) 14);
|
||||
session.setProducer( REGISTRY_PRODUCER);
|
||||
buffer.flip();
|
||||
session.queue(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package ms.net.event;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import ms.net.IoReadEvent;
|
||||
import ms.net.IoSession;
|
||||
import ms.net.packet.WorldPacketRepository;
|
||||
|
||||
/**
|
||||
* Handles world packet reading events.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class PacketReadEvent extends IoReadEvent {
|
||||
|
||||
/**
|
||||
* The packet sizes.
|
||||
*/
|
||||
private static final int[] PACKET_SIZE = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PacketReadEvent} {@code Object}.
|
||||
* @param session The I/O session.
|
||||
* @param buffer The buffer to read from.
|
||||
*/
|
||||
public PacketReadEvent(IoSession session, ByteBuffer buffer) {
|
||||
super(session, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(IoSession session, ByteBuffer buffer) {
|
||||
int last = -1;
|
||||
while (buffer.hasRemaining()) {
|
||||
int opcode = buffer.get() & 0xFF;
|
||||
if (opcode >= PACKET_SIZE.length) {
|
||||
break;
|
||||
}
|
||||
int header = PACKET_SIZE[opcode];
|
||||
int size = header;
|
||||
if (header < 0) {
|
||||
size = getPacketSize(buffer, opcode, header, last);
|
||||
}
|
||||
if (size == -1) {
|
||||
break;
|
||||
}
|
||||
if (buffer.remaining() < size) {
|
||||
switch (header) {
|
||||
case -2:
|
||||
queueBuffer(opcode, size >> 8, size);
|
||||
break;
|
||||
case -1:
|
||||
queueBuffer(opcode, size);
|
||||
break;
|
||||
default:
|
||||
queueBuffer(opcode);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
byte[] data = new byte[size];
|
||||
buffer.get(data);
|
||||
last = opcode;
|
||||
try {
|
||||
WorldPacketRepository.handleIncoming(session, opcode, ByteBuffer.wrap(data));
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the packet size for the given opcode.
|
||||
* @param buffer The buffer.
|
||||
* @param opcode The opcode.
|
||||
* @param header The packet header.
|
||||
* @param last The last opcode.
|
||||
* @return The packet size.
|
||||
*/
|
||||
private int getPacketSize(ByteBuffer buffer, int opcode, int header, int last) {
|
||||
if (header == -1) {
|
||||
if (buffer.remaining() < 1) {
|
||||
queueBuffer(opcode);
|
||||
return -1;
|
||||
}
|
||||
return buffer.get() & 0xFF;
|
||||
}
|
||||
if (header == -2) {
|
||||
if (buffer.remaining() < 2) {
|
||||
queueBuffer(opcode);
|
||||
return -1;
|
||||
}
|
||||
return buffer.getShort() & 0xFFFF;
|
||||
}
|
||||
System.err.println("Invalid packet [opcode=" + opcode + ", last=" + last + ", queued=" + usedQueuedBuffer + "]!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package ms.net.event;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import ms.net.IoSession;
|
||||
import ms.net.IoWriteEvent;
|
||||
import ms.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* Handles world packet writing events.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class PacketWriteEvent extends IoWriteEvent {
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PacketWriteEvent} {@code Object}.
|
||||
* @param session The I/O session.
|
||||
* @param context The packet context.
|
||||
*/
|
||||
public PacketWriteEvent(IoSession session, Object context) {
|
||||
super(session, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoSession session, Object context) {
|
||||
IoBuffer b = (IoBuffer) context;
|
||||
int size = b.toByteBuffer().position();
|
||||
ByteBuffer buffer = ByteBuffer.allocate(1 + size + b.getHeader().ordinal());
|
||||
buffer.put((byte) b.opcode());
|
||||
switch (b.getHeader()) {
|
||||
case NORMAL:
|
||||
break;
|
||||
case BYTE:
|
||||
buffer.put((byte) size);
|
||||
break;
|
||||
case SHORT:
|
||||
buffer.putShort((short) size);
|
||||
break;
|
||||
}
|
||||
buffer.put((ByteBuffer) b.toByteBuffer().flip());
|
||||
session.queue((ByteBuffer) buffer.flip());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package ms.net.event;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import ms.ServerConstants;
|
||||
import ms.net.IoReadEvent;
|
||||
import ms.net.IoSession;
|
||||
import ms.world.WorldDatabase;
|
||||
import ms.system.util.ByteBufferUtils;
|
||||
import ms.world.info.CountryFlag;
|
||||
import ms.world.info.WorldInfo;
|
||||
|
||||
/**
|
||||
* Handles world registry read events.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class RegistryReadEvent extends IoReadEvent {
|
||||
|
||||
/**
|
||||
* The string check.
|
||||
*/
|
||||
private static final String CHECK = "12x4578f5g45hrdjiofed59898";
|
||||
//kratos = 666x14x88x28shhhwpwwb&h
|
||||
//12x4578f5g45hrdjiofed59898
|
||||
|
||||
/**
|
||||
* Constructs a new {@code RegistryReadEvent} {@code Object}.
|
||||
* @param session The session.
|
||||
* @param buffer The buffer to read.
|
||||
*/
|
||||
public RegistryReadEvent(IoSession session, ByteBuffer buffer) {
|
||||
super(session, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(IoSession session, ByteBuffer buffer) {
|
||||
int worldId = buffer.get() & 0xFF;
|
||||
if (buffer.remaining() < 2) {
|
||||
queueBuffer(worldId);
|
||||
return;
|
||||
}
|
||||
int revision = buffer.getInt();
|
||||
int country = buffer.get() & 0xFF;
|
||||
boolean members = buffer.get() == 1;
|
||||
boolean pvp = buffer.get() == 1;
|
||||
boolean quickChat = buffer.get() == 1;
|
||||
boolean lootshare = buffer.get() == 1;
|
||||
String activity = ByteBufferUtils.getString(buffer);
|
||||
for (int i = 0; i < CHECK.length(); i++) {
|
||||
if ((char) buffer.get() != CHECK.charAt(i)) {
|
||||
session.write(3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (worldId >= ServerConstants.WORLD_LIMIT) {
|
||||
session.write(0);
|
||||
return;
|
||||
}
|
||||
if (WorldDatabase.isActive(worldId)) {
|
||||
session.write(2);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
WorldInfo info = new WorldInfo(worldId, session.getAddress(), revision, CountryFlag.values()[country], activity, members, pvp, quickChat, lootshare);
|
||||
WorldDatabase.register(info).configure(session);
|
||||
session.write(1);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
session.write(3);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package ms.net.event;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import ms.net.EventProducer;
|
||||
import ms.net.IoSession;
|
||||
import ms.net.IoWriteEvent;
|
||||
import ms.net.producer.PacketEventProducer;
|
||||
|
||||
/**
|
||||
* Handles game world registry writing events.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class RegistryWriteEvent extends IoWriteEvent {
|
||||
|
||||
/**
|
||||
* The event producer.
|
||||
*/
|
||||
public static final EventProducer PRODUCER = new PacketEventProducer();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code RegistryWriteEvent} {@code Object}.
|
||||
* @param session The I/O session.
|
||||
* @param context The writing context.
|
||||
*/
|
||||
public RegistryWriteEvent(IoSession session, Object context) {
|
||||
super(session, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(IoSession session, Object context) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(1);
|
||||
int opcode = (int) context;
|
||||
buffer.put((byte) opcode);
|
||||
buffer.flip();
|
||||
if (opcode == 1) {
|
||||
session.setProducer(PRODUCER);
|
||||
}
|
||||
session.queue(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,666 +0,0 @@
|
||||
package ms.net.packet;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import ms.system.util.ByteBufferUtils;
|
||||
|
||||
/**
|
||||
* Represents the buffer used for reading/writing packets.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public class IoBuffer {
|
||||
|
||||
/**
|
||||
* The bit masks.
|
||||
*/
|
||||
private static final int[] BIT_MASK = new int[32];
|
||||
|
||||
/**
|
||||
* The packet size.
|
||||
*/
|
||||
private int packetSize;
|
||||
|
||||
/**
|
||||
* The opcode.
|
||||
*/
|
||||
private final int opcode;
|
||||
|
||||
/**
|
||||
* The packet header.
|
||||
*/
|
||||
private final PacketHeader header;
|
||||
|
||||
/**
|
||||
* The byte buffer.
|
||||
*/
|
||||
private ByteBuffer buf;
|
||||
|
||||
/**
|
||||
* The bit position.
|
||||
*/
|
||||
private int bitPosition = 0;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code IoBuffer} {@code Object}.
|
||||
*/
|
||||
public IoBuffer() {
|
||||
this(-1, PacketHeader.NORMAL, ByteBuffer.allocate(2048));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code IoBuffer} {@code Object}.
|
||||
* @param opcode The opcode.
|
||||
*/
|
||||
public IoBuffer(int opcode) {
|
||||
this(opcode, PacketHeader.NORMAL, ByteBuffer.allocate(2048));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code IoBuffer} {@code Object}.
|
||||
* @param opcode The opcode.
|
||||
* @param header The packet header.
|
||||
*/
|
||||
public IoBuffer(int opcode, PacketHeader header) {
|
||||
this(opcode, header, ByteBuffer.allocate((1 << 16) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code IoBuffer} {@code Object}.
|
||||
* @param opcode The opcode.
|
||||
* @param header The packet header.
|
||||
* @param buf The byte buffer.
|
||||
*/
|
||||
public IoBuffer(int opcode, PacketHeader header, ByteBuffer buf) {
|
||||
this.opcode = opcode;
|
||||
this.header = header;
|
||||
this.buf = buf;
|
||||
}
|
||||
|
||||
static {
|
||||
for (int i = 0; i < 32; i++) {
|
||||
BIT_MASK[i] = (1 << i) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer clear() {
|
||||
buf.clear();
|
||||
bitPosition = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer put(int val) {
|
||||
buf.put((byte) val);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param datas
|
||||
* @param offset
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putBytes(byte[] datas, int offset, int len) {
|
||||
for (int i = offset; i < len; i++) {
|
||||
put(datas[i]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public final void getBytes(byte data[], int off, int len) {
|
||||
for (int k = off; k < len + off; k++) {
|
||||
data[k] = data[off++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putA(int val) {
|
||||
buf.put((byte) (val + 128));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putC(int val) {
|
||||
buf.put((byte) -val);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putS(int val) {
|
||||
buf.put((byte) (128 - val));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putTri(int val) {
|
||||
buf.put((byte) (val >> 16));
|
||||
buf.put((byte) (val >> 8));
|
||||
buf.put((byte) val);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putShort(int val) {
|
||||
buf.putShort((short) val);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putLEShort(int val) {
|
||||
buf.put((byte) val);
|
||||
buf.put((byte) (val >> 8));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putShortA(int val) {
|
||||
buf.put((byte) (val >> 8));
|
||||
buf.put((byte) (val + 128));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putLEShortA(int val) {
|
||||
buf.put((byte) (val + 128));
|
||||
buf.put((byte) (val >> 8));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putInt(int val) {
|
||||
buf.putInt(val);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putLEInt(int val) {
|
||||
buf.put((byte) val);
|
||||
buf.put((byte) (val >> 8));
|
||||
buf.put((byte) (val >> 16));
|
||||
buf.put((byte) (val >> 24));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putIntA(int val) {
|
||||
buf.put((byte) (val >> 8));
|
||||
buf.put((byte) val);
|
||||
buf.put((byte) (val >> 24));
|
||||
buf.put((byte) (val >> 16));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putIntB(int val) {
|
||||
buf.put((byte) (val >> 16));
|
||||
buf.put((byte) (val >> 24));
|
||||
buf.put((byte) val);
|
||||
buf.put((byte) (val >> 8));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putLong(long val) {
|
||||
buf.putLong(val);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putSmart(int val) {
|
||||
if (val > Byte.MAX_VALUE) {
|
||||
buf.putShort((short) (val + 32768));
|
||||
} else {
|
||||
buf.put((byte) val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putIntSmart(int val) {
|
||||
if (val > Short.MAX_VALUE) {
|
||||
buf.putInt(val + 32768);
|
||||
} else {
|
||||
buf.putShort((short) val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putString(String val) {
|
||||
buf.put(val.getBytes(StandardCharsets.UTF_8));
|
||||
buf.put((byte) 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putJagString(String val) {
|
||||
buf.put((byte) 0);
|
||||
buf.put(val.getBytes(StandardCharsets.UTF_8));
|
||||
buf.put((byte) 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putJagString2(String val) {
|
||||
byte[] packed = new byte[256];
|
||||
int length = ByteBufferUtils.packGJString2(0, packed, val);
|
||||
buf.put((byte) 0).put(packed, 0, length).put((byte) 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer put(byte[] val) {
|
||||
buf.put(val);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a byte array as byte A in reverse.
|
||||
* @param data The data to put.
|
||||
* @param start The start index.
|
||||
* @param offset The offset.
|
||||
*/
|
||||
public void putReverseA(byte[] data, int start, int offset) {
|
||||
for (int i = offset + start; i >= start; i--) {
|
||||
putA(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param numBits
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putBits(int numBits, int value) {
|
||||
int bytePos = getBitPosition() >> 3;
|
||||
int bitOffset = 8 - (getBitPosition() & 7);
|
||||
bitPosition += numBits;
|
||||
for (; numBits > bitOffset; bitOffset = 8) {
|
||||
byte b = buf.get(bytePos);
|
||||
buf.put(bytePos, b &= ~BIT_MASK[bitOffset]);
|
||||
buf.put(bytePos++, b |= value >> numBits - bitOffset & BIT_MASK[bitOffset]);
|
||||
numBits -= bitOffset;
|
||||
}
|
||||
byte b = buf.get(bytePos);
|
||||
if (numBits == bitOffset) {
|
||||
buf.put(bytePos, b &= ~BIT_MASK[bitOffset]);
|
||||
buf.put(bytePos, b |= value & BIT_MASK[bitOffset]);
|
||||
} else {
|
||||
buf.put(bytePos, b &= ~(BIT_MASK[numBits] << bitOffset - numBits));
|
||||
buf.put(bytePos, b |= (value & BIT_MASK[numBits]) << bitOffset - numBits);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param buffer
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer put(IoBuffer buffer) {
|
||||
buffer.toByteBuffer().flip();
|
||||
buf.put(buffer.toByteBuffer());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param buffer
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer putA(IoBuffer buffer) {
|
||||
buffer.toByteBuffer().flip();
|
||||
while (buffer.toByteBuffer().hasRemaining()) {
|
||||
putA(buffer.toByteBuffer().get());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param buffer
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer put(ByteBuffer buffer) {
|
||||
buf.put(buffer);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer setBitAccess() {
|
||||
bitPosition = buf.position() * 8;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer setByteAccess() {
|
||||
buf.position((getBitPosition() + 7) / 8);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int get() {
|
||||
return buf.get();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getA() {
|
||||
return (buf.get() & 0xFF) - 128;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getC() {
|
||||
return -buf.get();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getS() {
|
||||
return 128 - buf.get();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getTri() {
|
||||
return ((buf.get() << 16) & 0xFF) | ((buf.get() << 8) & 0xFF) | (buf.get() & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getShort() {
|
||||
return buf.getShort();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getLEShort() {
|
||||
return (buf.get() & 0xFF) | ((buf.get() & 0xFF) << 8);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getShortA() {
|
||||
return ((buf.get() & 0xFF) << 8) | (buf.get() - 128 & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getLEShortA() {
|
||||
return (buf.get() - 128 & 0xFF) | ((buf.get() & 0xFF) << 8);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getInt() {
|
||||
return buf.getInt();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getLEInt() {
|
||||
return (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8)
|
||||
+ ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 24);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getIntA() {
|
||||
return ((buf.get() & 0xFF) << 8) + (buf.get() & 0xFF)+ ((buf.get() & 0xFF) << 24) + ((buf.get() & 0xFF) << 16);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getIntB() {
|
||||
return ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 24)
|
||||
+ (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public long getLongL() {
|
||||
long first = getIntB();
|
||||
long second = getIntB();
|
||||
if (second < 0)
|
||||
second = second & 0xffffffffL;
|
||||
return (first << 32) + second;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public long getLong() {
|
||||
return buf.getLong();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getIntSmart() {
|
||||
int peek = buf.getShort(buf.position());
|
||||
if (peek <= Short.MAX_VALUE) {
|
||||
return buf.getShort() & 0xFFFF;
|
||||
}
|
||||
return buf.getInt() - 32768;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getString() {
|
||||
return ByteBufferUtils.getString(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getJagString() {
|
||||
buf.get();
|
||||
return ByteBufferUtils.getString(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param is
|
||||
* @param offset
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
public IoBuffer getReverseA(byte[] is, int offset, int length) {
|
||||
for (int i = (offset + length - 1); i >= offset; i--) {
|
||||
is[i] = (byte) (buf.get() - 128);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ByteBuffer toByteBuffer() {
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int opcode() {
|
||||
return opcode;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int readableBytes() {
|
||||
return buf.capacity() - buf.remaining();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public PacketHeader getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public byte[] array() {
|
||||
return buf.array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the packetSize.
|
||||
*/
|
||||
public int getPacketSize() {
|
||||
return packetSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param packetSize the packetSize to set.
|
||||
*/
|
||||
public void setPacketSize(int packetSize) {
|
||||
this.packetSize = packetSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bitPosition.
|
||||
* @return The bitPosition.
|
||||
*/
|
||||
public int getBitPosition() {
|
||||
return bitPosition;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package ms.net.packet
|
||||
|
||||
/**
|
||||
* Represents the types of packet headers.
|
||||
* @author Emperor
|
||||
*/
|
||||
enum class PacketHeader {
|
||||
|
||||
/**
|
||||
* The normal packet header.
|
||||
*/
|
||||
NORMAL,
|
||||
|
||||
/**
|
||||
* The byte packet header.
|
||||
*/
|
||||
BYTE,
|
||||
|
||||
/**
|
||||
* The short packet header.
|
||||
*/
|
||||
SHORT
|
||||
}
|
||||
@@ -1,555 +0,0 @@
|
||||
package ms.net.packet
|
||||
|
||||
import ms.net.IoSession
|
||||
import ms.system.PunishmentStorage
|
||||
import ms.system.communication.ClanRank
|
||||
import ms.system.communication.ClanRepository
|
||||
import ms.system.communication.CommunicationInfo
|
||||
import ms.system.util.ManagementConstants.WORLD_HOP_DELAY
|
||||
import ms.world.GameServer
|
||||
import ms.world.PlayerSession
|
||||
import ms.world.WorldDatabase
|
||||
import ms.world.info.Response
|
||||
import ms.world.info.UIDInfo
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
/**
|
||||
* Repository class for world packets.
|
||||
* @author Emperor
|
||||
*/
|
||||
object WorldPacketRepository {
|
||||
/**
|
||||
* Sends the player registry response.
|
||||
* @param server The game server.
|
||||
* @param player The player session.
|
||||
* @param response The registry response.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun sendRegistryResponse(server: GameServer, player: PlayerSession, response: Response) {
|
||||
val buffer = IoBuffer(0, PacketHeader.BYTE)
|
||||
buffer.putString(player.username)
|
||||
buffer.put(response.opcode())//byte
|
||||
if (response == Response.MOVING_WORLD) {
|
||||
val delay: Long = WORLD_HOP_DELAY - (System.currentTimeMillis() - player.disconnectionTime)
|
||||
buffer.put((delay / 1000).toInt())
|
||||
}
|
||||
server.session.write(buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the player.
|
||||
* @param player The player.
|
||||
* @param message The message to send.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun sendPlayerMessage(player: PlayerSession?, message: String) {
|
||||
if (player == null) {
|
||||
return
|
||||
}
|
||||
val buffer = IoBuffer(2, PacketHeader.BYTE)
|
||||
buffer.putString(player.username)
|
||||
buffer.putString(message)
|
||||
player.world.session.write(buffer)
|
||||
}
|
||||
|
||||
fun sendPlayerMessage(player: PlayerSession?, messages: Array<String>) {
|
||||
if (player == null) {
|
||||
return
|
||||
}
|
||||
for (message in messages) sendPlayerMessage(player, message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the contact information.
|
||||
* @param player The player.
|
||||
*/
|
||||
fun sendContactInformation(player: PlayerSession) {
|
||||
val info = player.communication
|
||||
val buffer = IoBuffer(3, PacketHeader.SHORT)
|
||||
buffer.putString(player.username)
|
||||
buffer.put(info.contacts.size)
|
||||
for (contact in info.contacts.keys) {
|
||||
buffer.putString(contact)
|
||||
buffer.put(info.getRank(contact).ordinal)
|
||||
buffer.put(CommunicationInfo.getWorldId(player, contact))
|
||||
}
|
||||
buffer.put(info.blocked.size)
|
||||
for (contact in info.blocked) {
|
||||
buffer.putString(contact)
|
||||
}
|
||||
if (info.currentClan == null) {
|
||||
buffer.put(0)
|
||||
} else {
|
||||
buffer.put(1)
|
||||
buffer.putString(info.currentClan)
|
||||
}
|
||||
player.world.session.write(buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a contact update.
|
||||
* @param player The player who's contacts we're changing.
|
||||
* @param contact The contact to update.
|
||||
* @param block If we're updating the blocked list.
|
||||
* @param remove If the contact should be removed.
|
||||
* @param worldId The world id of the contact.
|
||||
* @param rank The clan rank.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun sendContactUpdate(
|
||||
player: PlayerSession,
|
||||
contact: String,
|
||||
block: Boolean,
|
||||
remove: Boolean,
|
||||
worldId: Int,
|
||||
rank: ClanRank?
|
||||
) {
|
||||
val buffer = IoBuffer(4, PacketHeader.BYTE)
|
||||
buffer.putString(player.username)
|
||||
buffer.putString(contact)
|
||||
buffer.put((if (block) 1 else 0))
|
||||
if (rank != null) {
|
||||
buffer.put((2 + rank.ordinal))
|
||||
} else {
|
||||
buffer.put((if (remove) 1 else 0))
|
||||
if (!block && !remove) {
|
||||
buffer.put(worldId)
|
||||
}
|
||||
}
|
||||
player.world.session.write(buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a clan message.
|
||||
* @param player The player to send the message to.
|
||||
* @param p The player sending the message.
|
||||
* @param message The message to send.
|
||||
* @param type The message type.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun sendMessage(player: PlayerSession, p: PlayerSession, type: Int, message: String) {
|
||||
val buffer = IoBuffer(5, PacketHeader.BYTE)
|
||||
buffer.putString(player.username)
|
||||
buffer.putString(p.username)
|
||||
buffer.put(type)
|
||||
buffer.put(p.chatIcon)
|
||||
buffer.putString(message)
|
||||
println("Send Message: ${player.username} -> ${p.username} T: $type ICO: ${p.chatIcon} $message")
|
||||
player.world.session.write(buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends clan information to the server.
|
||||
* @param server The server.
|
||||
* @param clan The clan.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun sendClanInformation(server: GameServer, clan: ClanRepository) {
|
||||
val buffer = IoBuffer(6, PacketHeader.SHORT)
|
||||
buffer.putString(clan.owner.username)
|
||||
buffer.putString(clan.name)
|
||||
var length = clan.players.size
|
||||
if (length > ClanRepository.MAX_MEMBERS) {
|
||||
length = ClanRepository.MAX_MEMBERS
|
||||
}
|
||||
buffer.put(length)
|
||||
for (i in 0 until length) {
|
||||
val player = clan.players[i]
|
||||
buffer.putString(player.username)
|
||||
buffer.put(player.worldId)
|
||||
buffer.put(clan.getRank(player).ordinal)
|
||||
}
|
||||
buffer.put(clan.joinRequirement.ordinal)
|
||||
buffer.put(clan.kickRequirement.ordinal)
|
||||
buffer.put(clan.messageRequirement.ordinal)
|
||||
buffer.put(clan.lootRequirement.ordinal)
|
||||
server.session.write(buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the leave clan packet.
|
||||
* @param player The player leaving the clan.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun sendLeaveClan(player: PlayerSession) {
|
||||
val buffer = IoBuffer(7, PacketHeader.BYTE)
|
||||
buffer.putString(player.username)
|
||||
player.world.session.write(buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the player login notification.
|
||||
* @param server The server.
|
||||
* @param player The player logging in.
|
||||
* @param names The names.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun notifyPlayers(server: GameServer, player: PlayerSession, names: List<String>) {
|
||||
val buffer = IoBuffer(8, PacketHeader.SHORT)
|
||||
buffer.putString(player.username)
|
||||
buffer.put(player.worldId)
|
||||
buffer.put(names.size)
|
||||
for (name in names) {
|
||||
buffer.putString(name)
|
||||
}
|
||||
server.session.write(buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the game server a player logged out.
|
||||
* @param server The game server to notify.
|
||||
* @param player The player logging out.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun notifyLogout(server: GameServer, player: PlayerSession) {
|
||||
val buffer = IoBuffer(9, PacketHeader.BYTE)
|
||||
buffer.putString(player.username)
|
||||
server.session.write(buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the update countdown to the server.
|
||||
* @param server The server.
|
||||
* @param ticks The amount of ticks left.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun sendUpdate(server: GameServer, ticks: Int) {
|
||||
val buffer = IoBuffer(10)
|
||||
buffer.putInt(ticks)
|
||||
server.session.write(buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the punishment update packet.
|
||||
* @param world The world to send the packet to.
|
||||
* @param key The punishment key.
|
||||
* @param type The punishment type.
|
||||
* @param duration The duration of the punishment.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun sendPunishUpdate(world: GameServer, key: String, type: Int, duration: Long) {
|
||||
val buffer = IoBuffer(11, PacketHeader.BYTE)
|
||||
buffer.putString(key)
|
||||
buffer.put(type)
|
||||
buffer.putLong(duration)
|
||||
world.session.write(buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a configuration reload.
|
||||
* @param world the world.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun sendConfigReload(world: GameServer) {
|
||||
world.session.write(IoBuffer(15, PacketHeader.BYTE))
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles incoming world packets.
|
||||
* @param session The I/O session.
|
||||
* @param opcode The opcode.
|
||||
* @param b The buffer to read from.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun handleIncoming(session: IoSession, opcode: Int, b: ByteBuffer) {
|
||||
val buffer = IoBuffer(opcode, PacketHeader.NORMAL, b)
|
||||
val server = session.gameServer
|
||||
when (opcode) {
|
||||
0 -> handlePlayerRegistration(server, buffer)
|
||||
1 -> handlePlayerRemoval(server, buffer)
|
||||
2 -> handlePunishment(server, buffer)
|
||||
3 -> handleCommunicationRequest(server, buffer)
|
||||
4, 5 -> handleContactUpdate(server, buffer, opcode == 5)
|
||||
6 -> handleJoinClan(server, buffer)
|
||||
7 -> handleClanRename(server, buffer)
|
||||
8 -> handleClanSetting(server, buffer)
|
||||
9 -> handleClanKick(server, buffer)
|
||||
10 -> handleClanMessage(server, buffer)
|
||||
11 -> handlePrivateMessage(server, buffer)
|
||||
12 -> handleClanInfoRequest(server, buffer)
|
||||
13 -> handleChatSetting(server, buffer)
|
||||
14 -> handleInfoUpdate(server, buffer)
|
||||
else -> System.err.println("Handling incoming packet [opcode=" + opcode + ", size=" + b.limit() + "].")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the info of a player update.
|
||||
* @param server the server.
|
||||
* @param buffer the buffer.
|
||||
*/
|
||||
private fun handleInfoUpdate(server: GameServer, buffer: IoBuffer) {
|
||||
val username = buffer.string
|
||||
val player = server.players[username]
|
||||
if (player != null) {
|
||||
player.chatIcon = buffer.get()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a player registration.
|
||||
* @param server The game server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handlePlayerRegistration(server: GameServer, buffer: IoBuffer) {
|
||||
val username = buffer.string
|
||||
val password = buffer.string
|
||||
val ipAddress = buffer.string
|
||||
val macAddress = buffer.string
|
||||
val compName = buffer.string
|
||||
val serial = buffer.string
|
||||
val rights = buffer.int
|
||||
val chatIcon = buffer.get()
|
||||
val uid = UIDInfo(ipAddress, compName, macAddress, serial)
|
||||
val player = PlayerSession(username, password, UIDInfo(ipAddress, compName, macAddress, serial))
|
||||
if (WorldDatabase.isActivePlayer(username)) {
|
||||
sendRegistryResponse(server, player, Response.ALREADY_ONLINE)
|
||||
return
|
||||
}
|
||||
player.uid = uid
|
||||
player.rights = rights
|
||||
player.chatIcon = chatIcon
|
||||
if (PunishmentStorage.isSystemBanned(uid)) {
|
||||
sendRegistryResponse(server, player, Response.BANNED)
|
||||
return
|
||||
}
|
||||
player.parse()
|
||||
if (player.isBanned) {
|
||||
sendRegistryResponse(server, player, Response.ACCOUNT_DISABLED)
|
||||
return
|
||||
}
|
||||
if (player.lastWorld != server.info.worldId && player.hasMovedWorld()) {
|
||||
sendRegistryResponse(server, player, Response.MOVING_WORLD)
|
||||
return
|
||||
}
|
||||
server.register(player)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the removal of a player.
|
||||
* @param server The game server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handlePlayerRemoval(server: GameServer, buffer: IoBuffer) {
|
||||
val username = buffer.string
|
||||
val session = server.players[username]
|
||||
if (session != null) {
|
||||
session.isActive = false
|
||||
val player = server.players.remove(username)
|
||||
if (player != null) {
|
||||
session.remove()
|
||||
}
|
||||
session.worldId = 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a player registration.
|
||||
* @param server The game server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handlePunishment(server: GameServer, buffer: IoBuffer) {
|
||||
val type = buffer.get() and 0xFF
|
||||
val target = buffer.string
|
||||
val duration = buffer.long
|
||||
val staff = buffer.string
|
||||
PunishmentStorage.handlePunishment(staff, target, type, duration)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the communication info request packet.
|
||||
* @param server The game server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handleCommunicationRequest(server: GameServer, buffer: IoBuffer) {
|
||||
val username = buffer.string
|
||||
val player = server.players[username] ?: return
|
||||
sendContactInformation(player)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a contact update packet.
|
||||
* @param server The server.
|
||||
* @param buffer The buffer to read from.
|
||||
* @param block If the list is for blocked players.
|
||||
*/
|
||||
private fun handleContactUpdate(server: GameServer, buffer: IoBuffer, block: Boolean) {
|
||||
val username = buffer.string
|
||||
val player = server.players[username] ?: return
|
||||
val contact = buffer.string
|
||||
when (buffer.get()) {
|
||||
0 -> {
|
||||
if (block) {
|
||||
player.communication.block(contact)
|
||||
}
|
||||
player.communication.add(contact)
|
||||
}
|
||||
1 -> player.communication.remove(contact, block)
|
||||
2 -> player.communication.updateClanRank(contact, ClanRank.values()[buffer.get()])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a clan related packet.
|
||||
* @param server The game server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handleJoinClan(server: GameServer, buffer: IoBuffer) {
|
||||
val name = buffer.string
|
||||
val clanName = buffer.string
|
||||
val player = server.players[name]
|
||||
if (player == null || !player.isActive) {
|
||||
System.err.println("Invalid player specified in clan packet!")
|
||||
return
|
||||
}
|
||||
if (player.clan != null) {
|
||||
player.clan.leave(player, true)
|
||||
return
|
||||
}
|
||||
if (clanName.length < 1) {
|
||||
sendLeaveClan(player)
|
||||
return
|
||||
}
|
||||
val clan = ClanRepository.get(server, clanName)
|
||||
if (clan == null) {
|
||||
sendPlayerMessage(
|
||||
player,
|
||||
arrayOf(
|
||||
"The channel you tried to join does not exist.",
|
||||
"Try joining the main clan named '2009Scape'.:clan:"
|
||||
)
|
||||
)
|
||||
return
|
||||
}
|
||||
clan.enter(player)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles renaming a clan.
|
||||
* @param server The server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handleClanRename(server: GameServer, buffer: IoBuffer) {
|
||||
val username = buffer.string
|
||||
val name = buffer.string
|
||||
val player = server.players[username]
|
||||
if (player == null || !player.isActive) {
|
||||
return
|
||||
}
|
||||
val clan = ClanRepository.getClans()[username]
|
||||
player.communication.clanName = name
|
||||
if (clan != null) {
|
||||
if (name.isEmpty()) {
|
||||
clan.clean(true)
|
||||
} else {
|
||||
clan.rename(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles changing clan settings packet.
|
||||
* @param server The game server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handleClanSetting(server: GameServer, buffer: IoBuffer) {
|
||||
val username = buffer.string
|
||||
val type = buffer.get()
|
||||
val rank = if (type < 4) ClanRank.values()[buffer.get() and 0xFF] else null
|
||||
val player = server.players[username]
|
||||
if (player == null || !player.isActive) {
|
||||
return
|
||||
}
|
||||
val clan = ClanRepository.get(server, username)
|
||||
when (type) {
|
||||
0 -> {
|
||||
player.communication.joinRequirement = rank
|
||||
clan?.clean(false)
|
||||
}
|
||||
1 -> player.communication.messageRequirement = rank
|
||||
2 -> {
|
||||
player.communication.kickRequirement = rank
|
||||
clan?.update()
|
||||
}
|
||||
3 -> player.communication.lootRequirement = rank
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles kicking a player from the clan.
|
||||
* @param server The game server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handleClanKick(server: GameServer, buffer: IoBuffer) {
|
||||
val username = buffer.string
|
||||
val playerName = buffer.string
|
||||
val player = server.players[username]
|
||||
if (player == null || !player.isActive || player.clan == null) {
|
||||
return
|
||||
}
|
||||
val target = WorldDatabase.getPlayer(playerName)
|
||||
if (target == null || !target.isActive) {
|
||||
return
|
||||
}
|
||||
player.clan.kick(player, target)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a clan message.
|
||||
* @param server The game server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handleClanMessage(server: GameServer, buffer: IoBuffer) {
|
||||
val username = buffer.string
|
||||
val message = buffer.string
|
||||
val player = server.players[username]
|
||||
if (player == null || !player.isActive || player.clan == null) {
|
||||
return
|
||||
}
|
||||
player.clan.message(player, message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a clan message.
|
||||
* @param server The game server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handlePrivateMessage(server: GameServer, buffer: IoBuffer) {
|
||||
val username = buffer.string
|
||||
val receiver = buffer.string
|
||||
val message = buffer.string
|
||||
val player = server.players[username]
|
||||
if (player == null || !player.isActive) {
|
||||
return
|
||||
}
|
||||
player.communication.sendMessage(receiver, message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a clan information request packet.
|
||||
* @param server The server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handleClanInfoRequest(server: GameServer, buffer: IoBuffer) {
|
||||
val name = buffer.string
|
||||
val clan = ClanRepository.get(server, name) ?: return
|
||||
sendClanInformation(server, clan)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a chat setting update packet.
|
||||
* @param server The server.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
private fun handleChatSetting(server: GameServer, buffer: IoBuffer) {
|
||||
val name = buffer.string
|
||||
val publicSetting = buffer.get()
|
||||
val privateSetting = buffer.get()
|
||||
val tradeSetting = buffer.get()
|
||||
val player = server.players[name]
|
||||
if (player == null || !player.isActive) {
|
||||
return
|
||||
}
|
||||
player.communication.updateSettings(publicSetting, privateSetting, tradeSetting)
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package ms.net.producer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import ms.net.EventProducer;
|
||||
import ms.net.IoReadEvent;
|
||||
import ms.net.IoSession;
|
||||
import ms.net.IoWriteEvent;
|
||||
import ms.net.event.HSReadEvent;
|
||||
import ms.net.event.HSWriteEvent;
|
||||
|
||||
/**
|
||||
* Produces I/O events for the handshake protocol.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class HSEventProducer implements EventProducer {
|
||||
|
||||
@Override
|
||||
public IoReadEvent produceReader(IoSession session, ByteBuffer buffer) {
|
||||
return new HSReadEvent(session, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IoWriteEvent produceWriter(IoSession session, Object context) {
|
||||
return new HSWriteEvent(session, context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package ms.net.producer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import ms.net.EventProducer;
|
||||
import ms.net.IoReadEvent;
|
||||
import ms.net.IoSession;
|
||||
import ms.net.IoWriteEvent;
|
||||
import ms.net.event.PacketReadEvent;
|
||||
import ms.net.event.PacketWriteEvent;
|
||||
|
||||
/**
|
||||
* The packet event producer.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class PacketEventProducer implements EventProducer {
|
||||
|
||||
@Override
|
||||
public IoReadEvent produceReader(IoSession session, ByteBuffer buffer) {
|
||||
return new PacketReadEvent(session, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IoWriteEvent produceWriter(IoSession session, Object context) {
|
||||
return new PacketWriteEvent(session, context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package ms.net.producer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import ms.net.EventProducer;
|
||||
import ms.net.IoReadEvent;
|
||||
import ms.net.IoSession;
|
||||
import ms.net.IoWriteEvent;
|
||||
import ms.net.event.RegistryReadEvent;
|
||||
import ms.net.event.RegistryWriteEvent;
|
||||
|
||||
/**
|
||||
* Handles world server registry.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class RegistryEventProducer implements EventProducer {
|
||||
|
||||
@Override
|
||||
public IoReadEvent produceReader(IoSession session, ByteBuffer buffer) {
|
||||
return new RegistryReadEvent(session, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IoWriteEvent produceWriter(IoSession session, Object context) {
|
||||
return new RegistryWriteEvent(session, context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package ms.system
|
||||
|
||||
/**
|
||||
* The operating systems
|
||||
* @author Clayton Williams
|
||||
*/
|
||||
enum class OperatingSystem {
|
||||
UNIX, WINDOWS
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
package ms.system;
|
||||
|
||||
import ms.net.packet.WorldPacketRepository;
|
||||
import ms.system.mysql.SQLManager;
|
||||
import ms.world.GameServer;
|
||||
import ms.world.PlayerSession;
|
||||
import ms.world.WorldDatabase;
|
||||
import ms.world.info.UIDInfo;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Used for storing and handling punishment data.
|
||||
* @author Emperor
|
||||
* @author Vexia
|
||||
*
|
||||
*/
|
||||
public final class PunishmentStorage {
|
||||
|
||||
/**
|
||||
* The type ids for IP, MAC and SERIAL bans.
|
||||
*/
|
||||
public static final int IP = 2, MAC = 3, SERIAL = 4;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PunishmentStorage} {@code Object}.
|
||||
*/
|
||||
public PunishmentStorage() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a punishment.
|
||||
* @param staff The name of the staff member dealing the punishment.
|
||||
* @param target The target.
|
||||
* @param type The punishment type.
|
||||
* @param duration The duration of the punishment (in milliseconds).
|
||||
*/
|
||||
public static void handlePunishment(String name, String target, int type, long duration) {
|
||||
PlayerSession staff = WorldDatabase.getPlayer(name);
|
||||
PlayerSession player = WorldDatabase.getPlayer(target, true);
|
||||
if (player == null) {
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "Player " + target + " is invalid!");
|
||||
return;
|
||||
}
|
||||
long end = Long.MAX_VALUE;
|
||||
if (duration != -1L && duration != 0L) {
|
||||
end = System.currentTimeMillis() + duration;
|
||||
} else if (duration == 0L) {
|
||||
end = 0L;
|
||||
}
|
||||
String key = "null";
|
||||
switch (type) {
|
||||
case 0: //Mute
|
||||
case 1: //Ban
|
||||
if (type == 1 && end == 0L) {
|
||||
unban(player.getIpAddress());
|
||||
unban(player.getMacAddress());
|
||||
unban(player.getSerialKey());
|
||||
}
|
||||
if (player.isActive()) {
|
||||
WorldPacketRepository.sendPunishUpdate(player.getWorld(), player.getUsername(), type, end);
|
||||
}
|
||||
notify(staff, type == 0 ? "mute" : "ban", target, end);
|
||||
Connection connection = SQLManager.getConnection();
|
||||
if (connection == null) {
|
||||
return;
|
||||
}
|
||||
PreparedStatement statement;
|
||||
try {
|
||||
statement = connection.prepareStatement("UPDATE members SET " + (type == 0 ? "muteTime" : "banTime") + "='" + end + "' WHERE username ='" + target + "'");
|
||||
statement.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
SQLManager.close(connection);
|
||||
return;
|
||||
} finally {
|
||||
SQLManager.close(connection);
|
||||
}
|
||||
return;
|
||||
case 2:
|
||||
ban(player.getIpAddress(), type);
|
||||
notify(staff, "IP-ban", target, end);
|
||||
notifyServers(key = player.getIpAddress(), type, end);
|
||||
break;
|
||||
case 3:
|
||||
ban(player.getMacAddress(), type);
|
||||
notify(staff, "MAC-ban", target, end);
|
||||
notifyServers(key = player.getMacAddress(), type, end);
|
||||
break;
|
||||
case 4:
|
||||
ban(player.getSerialKey(), type);
|
||||
notify(staff, "UID-ban", target, end);
|
||||
notifyServers(key = player.getSerialKey(), type, end);
|
||||
break;
|
||||
case 5:
|
||||
ban(player.getIpAddress(), 2);
|
||||
notifyServers(key = player.getIpAddress(), 2, end);
|
||||
ban(player.getMacAddress(), 3);
|
||||
notifyServers(key = player.getMacAddress(), 3, end);
|
||||
ban(player.getSerialKey(), 4);
|
||||
notifyServers(key = player.getSerialKey(), 4, end);
|
||||
notify(staff, "full ban", target, end);
|
||||
return;
|
||||
case 6: //Kick
|
||||
if (player.isActive()) {
|
||||
WorldPacketRepository.sendPunishUpdate(player.getWorld(), player.getUsername(), 6, end);
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "Successfully kicked player " + target + " from world " + player.getWorldId() + ".");
|
||||
} else {
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "Player " + target + " was already inactive.");
|
||||
}
|
||||
break;
|
||||
case 7: //Request info
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "[----------Player info----------]");
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "Name: " + player.getUsername());
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "IP address: " + player.getIpAddress());
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "MAC address: " + player.getMacAddress());
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "Serial key: " + player.getSerialKey());
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "Computer name: " + player.getComputerName());
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "[-------------------------------]");
|
||||
return;
|
||||
}
|
||||
notifyServers(key, type, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bans an address.
|
||||
* @param address the address.
|
||||
* @return {@code True} if banned.
|
||||
*/
|
||||
public static boolean ban(String address, int type) {
|
||||
if (address == null || address.length() == 0 || address.equals("To be filled by O.E.M.") || address.equals("To be filled by O.E.M") || address.equals("Base Board Serial Number")) {
|
||||
System.out.println("Error! Can't ban address " + address + " type = " + type + "!");
|
||||
return false;
|
||||
}
|
||||
if (isBanned(address)) {
|
||||
return false;
|
||||
}
|
||||
Connection connection = SQLManager.getConnection();
|
||||
if (connection == null) {
|
||||
return false;
|
||||
}
|
||||
PreparedStatement statement;
|
||||
try {
|
||||
statement = connection.prepareStatement("INSERT INTO punishments VALUES('" + address + "','" + type + "')");
|
||||
statement.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
SQLManager.close(connection);
|
||||
return false;
|
||||
} finally {
|
||||
SQLManager.close(connection);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbans an address.
|
||||
* @param address the address.
|
||||
* @return {@code True} if unbanned.
|
||||
*/
|
||||
public static boolean unban(String address) {
|
||||
Connection connection = SQLManager.getConnection();
|
||||
if (connection == null) {
|
||||
return false;
|
||||
}
|
||||
PreparedStatement statement;
|
||||
try {
|
||||
statement = connection.prepareStatement("DELETE from punishments WHERE address ='" + address + "'");
|
||||
statement.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
SQLManager.close(connection);
|
||||
return false;
|
||||
} finally {
|
||||
SQLManager.close(connection);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the punishing player of success.
|
||||
* @param staff The punishing player.
|
||||
* @param type The punishment type.
|
||||
* @param target The target name.
|
||||
* @param end The end time stamp of the punishment.
|
||||
*/
|
||||
private static void notify(PlayerSession staff, String type, String target, long end) {
|
||||
if (end <= System.currentTimeMillis()) {
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "Successfully removed punishment [type=" + type + ", player=" + target + "].");
|
||||
return;
|
||||
}
|
||||
WorldPacketRepository.sendPlayerMessage(staff, "Successfully punished player " + target + " [type=" + type + ", duration=" + getDuration(end) + "].");
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the game servers of a punishment update.
|
||||
* @param key The punishment key.
|
||||
* @param type The type.
|
||||
* @param duration The duration.
|
||||
*/
|
||||
public static void notifyServers(String key, int type, long duration) {
|
||||
for (GameServer server : WorldDatabase.getWorlds()) {
|
||||
if (server != null && server.isActive()) {
|
||||
WorldPacketRepository.sendPunishUpdate(server, key, type, duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the UID Info is banned.
|
||||
* @param info the info.
|
||||
* @return {@code True} if banned.
|
||||
*/
|
||||
public static boolean isSystemBanned(UIDInfo info) {
|
||||
return isBanned(info.getIp()) || isBanned(info.getMac()) || isBanned(info.getSerial());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checked if an address is banned.
|
||||
* @param address the address.
|
||||
* @param type the type.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean isBanned(String address) {
|
||||
Connection connection = SQLManager.getConnection();
|
||||
if (connection == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
ResultSet set = connection.createStatement().executeQuery("SELECT * FROM punishments WHERE address ='" + address +"'");
|
||||
if (set == null || !set.next()) {
|
||||
SQLManager.close(connection);
|
||||
return false;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
SQLManager.close(connection);
|
||||
return false;
|
||||
} finally {
|
||||
SQLManager.close(connection);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the duration string representation.
|
||||
* @param end The end time.
|
||||
* @return The string.
|
||||
*/
|
||||
private static String getDuration(long end) {
|
||||
String time = "indefinite time";
|
||||
if (end != Long.MAX_VALUE) {
|
||||
int days = (int) ((System.currentTimeMillis()) / (24 * 60 * 60_000));
|
||||
int hours = (int) (((24L * days * 60 * 60_000)) / (60 * 60_000));
|
||||
int minutes = (int) (((hours * (60 * 60_000))) / 60_000);
|
||||
time = days + "d, " + hours + "h, " + minutes + "m";
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package ms.system;
|
||||
|
||||
|
||||
import ms.Management;
|
||||
|
||||
/**
|
||||
* The shutdown sequence used for safely turning off the Management server.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class ShutdownSequence extends Thread {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (Management.active) {
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely shuts down the Management server.
|
||||
*/
|
||||
public static void shutdown() {
|
||||
System.out.println("Management server successfully shut down!");
|
||||
Management.active = false;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package ms.system.communication;
|
||||
|
||||
/**
|
||||
* Represents the rank of a clan member.
|
||||
* @author Emperor
|
||||
*/
|
||||
public enum ClanRank {
|
||||
NONE(-1, "Anyone"),
|
||||
FRIEND(0, "Any friends"),
|
||||
RECRUIT(1, "Recruit+"),
|
||||
CORPORAL(2, "Corporal+"),
|
||||
SERGEANT(3, "Sergeant+"),
|
||||
LIEUTENANT(4, "Lieutenant+"),
|
||||
CAPTAIN(5, "Captain+"),
|
||||
GENERAL(6, "General+"),
|
||||
OWNER(7, "Only me"),
|
||||
ADMINISTRATOR(127, "No-one");
|
||||
|
||||
/**
|
||||
* The value of the rank.
|
||||
*/
|
||||
private final int value;
|
||||
|
||||
/**
|
||||
* The requirement info.
|
||||
*/
|
||||
private final String info;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ClanRank} {@code Object}.
|
||||
* @param value The rank value.
|
||||
* @param info The requirement info.
|
||||
*/
|
||||
private ClanRank(int value, String info) {
|
||||
this.value = value;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value.
|
||||
* @return The value.
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the info.
|
||||
* @return The info.
|
||||
*/
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
@@ -1,337 +0,0 @@
|
||||
package ms.system.communication;
|
||||
|
||||
import ms.net.packet.WorldPacketRepository;
|
||||
import ms.system.util.StringUtils;
|
||||
import ms.world.GameServer;
|
||||
import ms.world.PlayerSession;
|
||||
import ms.world.WorldDatabase;
|
||||
import ms.world.info.UIDInfo;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Holds clan related information.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class ClanRepository {
|
||||
|
||||
/**
|
||||
* The mapping of active clans.
|
||||
*/
|
||||
private static final Map<String, ClanRepository> CLANS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The maximum amount of members to be in a clan chat.
|
||||
*/
|
||||
public static final int MAX_MEMBERS = 100;
|
||||
|
||||
/**
|
||||
* The owner's details.
|
||||
*/
|
||||
private PlayerSession owner;
|
||||
|
||||
/**
|
||||
* The list of players currently in the chat.
|
||||
*/
|
||||
private final List<PlayerSession> players = new ArrayList<>(MAX_MEMBERS);
|
||||
|
||||
/**
|
||||
* The banned players.
|
||||
*/
|
||||
private final Map<String, Long> banned = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ClanRepository} {@code Object}.
|
||||
*/
|
||||
private ClanRepository() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clan repository for the given username.
|
||||
* @param ownerName The clan owner's name.
|
||||
* @return The clan repository.
|
||||
*/
|
||||
public static ClanRepository get(GameServer server, String ownerName) {
|
||||
ClanRepository clan = CLANS.get(ownerName);
|
||||
if (clan != null) {
|
||||
return clan;
|
||||
}
|
||||
PlayerSession owner = WorldDatabase.getPlayer(ownerName);
|
||||
if (owner == null) {
|
||||
owner = new PlayerSession(ownerName, ownerName, new UIDInfo());
|
||||
owner.parse();
|
||||
}
|
||||
if (owner.getCommunication().getClanName().equals("")) {
|
||||
return null;
|
||||
}
|
||||
clan = new ClanRepository();
|
||||
clan.owner = owner;
|
||||
CLANS.put(ownerName, clan);
|
||||
return clan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enters the clan chat.
|
||||
* @param player The player.
|
||||
*/
|
||||
public void enter(PlayerSession player) {
|
||||
if (players.size() >= MAX_MEMBERS && !owner.getUsername().equals("2009scape")) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "The channel you tried to join is full.:clan:");
|
||||
return;
|
||||
}
|
||||
if (player != owner && player.getRights() != 2) {
|
||||
if (isBanned(player.getUsername()) || owner.getCommunication().getBlocked().contains(player.getUsername())) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "You are temporarily banned from this clan channel.:clan:");
|
||||
return;
|
||||
}
|
||||
ClanRank rank = getRank(player);
|
||||
if (rank.ordinal() < getJoinRequirement().ordinal()) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "You do not have a high enough rank to join this clan channel.:clan:");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!players.contains(player)) {
|
||||
players.add(player);
|
||||
}
|
||||
WorldPacketRepository.sendPlayerMessage(player, "Now talking in clan channel " + owner.getCommunication().getClanName() + ".:clan:");
|
||||
WorldPacketRepository.sendPlayerMessage(player, "To talk, start each line of chat with the / symbol.:clan:");
|
||||
player.getCommunication().setCurrentClan(owner.getUsername());
|
||||
player.setClan(this);
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves the clan chat.
|
||||
* @param player The player to leave.
|
||||
* @param remove If the player should be removed from the list.
|
||||
*/
|
||||
public void leave(PlayerSession player, boolean remove) {
|
||||
if (remove) {
|
||||
players.remove(player);
|
||||
update();
|
||||
if (players.size() < 1) {
|
||||
banned.clear();
|
||||
}
|
||||
}
|
||||
WorldPacketRepository.sendPlayerMessage(player, "You have left the channel.:clan:");
|
||||
player.setClan(null);
|
||||
player.getCommunication().setCurrentClan(null);
|
||||
if (player.isActive()) {
|
||||
WorldPacketRepository.sendLeaveClan(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to all players in the chat.
|
||||
* @param player The player sending the message.
|
||||
* @param message The message to send.
|
||||
*/
|
||||
public void message(PlayerSession player, String message) {
|
||||
if (player != owner && player.getRights() != 2) {
|
||||
ClanRank rank = getRank(player);
|
||||
if (rank.ordinal() < getMessageRequirement().ordinal()) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "You do not have a high enough rank to talk in this clan channel.:clan:");
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (Iterator<PlayerSession> it = players.iterator(); it.hasNext();) {
|
||||
PlayerSession p = it.next();
|
||||
if (p != null) {
|
||||
WorldPacketRepository.sendMessage(p, player, 2, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the clan chat.
|
||||
*/
|
||||
public void update() {
|
||||
for (GameServer server : WorldDatabase.getWorlds()) {
|
||||
if (server != null && server.isActive()) {
|
||||
WorldPacketRepository.sendClanInformation(server, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks a player from the clan chat.
|
||||
* @param player The player.
|
||||
*/
|
||||
public void kick(PlayerSession player, PlayerSession target) {
|
||||
ClanRank rank = getRank(target);
|
||||
if (target.getRights() == 2) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "You can't kick an administrator.:clan:");
|
||||
return;
|
||||
}
|
||||
System.out.println(rank + ", " + player.getUsername());
|
||||
if (player.getRights() < 1/*!= 2 && rank.ordinal() < getKickRequirement().ordinal()*/) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "You do not have a high enough rank to kick in this clan channel.:clan:");
|
||||
return;
|
||||
}
|
||||
if (target == owner) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "You can't kick the owner of this clan channel.:clan:");
|
||||
return;
|
||||
}
|
||||
if (target == player) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "You can't kick yourself.:clan:");
|
||||
return;
|
||||
}
|
||||
for (PlayerSession p : players) {
|
||||
WorldPacketRepository.sendMessage(p, player, 2, "[Attempting to kick/ban " + StringUtils.formatDisplayName(target.getUsername()) + " from this Clan Chat.]");
|
||||
}
|
||||
leave(target, true);
|
||||
banned.put(target.getUsername(), System.currentTimeMillis() + (3_600_000));
|
||||
WorldPacketRepository.sendPlayerMessage(target, "You have been kicked from the channel.:clan:");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rank for the given player.
|
||||
* @param player The player.
|
||||
* @return The rank.
|
||||
*/
|
||||
public ClanRank getRank(PlayerSession player) {
|
||||
ClanRank rank = owner.getCommunication().getContacts().get(player.getUsername());
|
||||
if (player.getRights() == 2 && player != owner) {
|
||||
return ClanRank.ADMINISTRATOR;
|
||||
}
|
||||
if (rank == null) {
|
||||
if (player == owner) {
|
||||
return ClanRank.OWNER;
|
||||
}
|
||||
return ClanRank.NONE;
|
||||
}
|
||||
return rank;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is banned.
|
||||
* @param username The username of the player.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
private boolean isBanned(String username) {
|
||||
Long time = banned.get(username);
|
||||
if (time == null) {
|
||||
return false;
|
||||
}
|
||||
if (time < System.currentTimeMillis()) {
|
||||
banned.remove(username);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the clan chat.
|
||||
* @param disable If the clan chat is getting disabled.
|
||||
*/
|
||||
public void clean(boolean disable) {
|
||||
for (Iterator<PlayerSession> it = players.iterator(); it.hasNext();) {
|
||||
PlayerSession player = it.next();
|
||||
boolean remove = disable;
|
||||
if (!remove) {
|
||||
remove = getRank(player).ordinal() < getJoinRequirement().getValue();
|
||||
}
|
||||
if (remove) {
|
||||
leave(player, false);
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
if (players.isEmpty()) {
|
||||
banned.clear();
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames the clan chat.
|
||||
* @param name The new clan name.
|
||||
*/
|
||||
public void rename(String name) {
|
||||
owner.getCommunication().setClanName(name);
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clan name.
|
||||
* @return The clan name.
|
||||
*/
|
||||
public String getName() {
|
||||
return owner.getCommunication().getClanName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the owner value.
|
||||
* @return The owner.
|
||||
*/
|
||||
public PlayerSession getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the owner value.
|
||||
* @param owner The owner to set.
|
||||
*/
|
||||
public void setOwner(PlayerSession owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the players value.
|
||||
* @return The players.
|
||||
*/
|
||||
public List<PlayerSession> getPlayers() {
|
||||
return players;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clans value.
|
||||
* @return The clans.
|
||||
*/
|
||||
public static Map<String, ClanRepository> getClans() {
|
||||
return CLANS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the joinRequirement value.
|
||||
* @return The joinRequirement.
|
||||
*/
|
||||
public ClanRank getJoinRequirement() {
|
||||
return owner.getCommunication().getJoinRequirement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the messageRequirement value.
|
||||
* @return The messageRequirement.
|
||||
*/
|
||||
public ClanRank getMessageRequirement() {
|
||||
return owner.getCommunication().getMessageRequirement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the kickRequirement value.
|
||||
* @return The kickRequirement.
|
||||
*/
|
||||
public ClanRank getKickRequirement() {
|
||||
return owner.getCommunication().getKickRequirement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lootRequirement value.
|
||||
* @return The lootRequirement.
|
||||
*/
|
||||
public ClanRank getLootRequirement() {
|
||||
return owner.getCommunication().getLootRequirement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the banned value.
|
||||
* @return The banned.
|
||||
*/
|
||||
public Map<String, Long> getBanned() {
|
||||
return banned;
|
||||
}
|
||||
}
|
||||
@@ -1,656 +0,0 @@
|
||||
package ms.system.communication;
|
||||
|
||||
import ms.ServerConstants;
|
||||
import ms.net.packet.WorldPacketRepository;
|
||||
import ms.system.util.ByteBufferUtils;
|
||||
import ms.system.util.StringUtils;
|
||||
import ms.world.GameServer;
|
||||
import ms.world.PlayerSession;
|
||||
import ms.world.WorldDatabase;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* Holds communication information.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class CommunicationInfo {
|
||||
|
||||
/**
|
||||
* The maximum list size.
|
||||
*/
|
||||
public static final int MAX_LIST_SIZE = 200;
|
||||
|
||||
/**
|
||||
* The clan ranks.
|
||||
*/
|
||||
private final Map<String, ClanRank> contacts = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The list of blocked players.
|
||||
*/
|
||||
private final List<String> blocked = new ArrayList<>(20);
|
||||
|
||||
/**
|
||||
* The player's clan name.
|
||||
*/
|
||||
private String clanName = "";
|
||||
|
||||
/**
|
||||
* The current clan this player is in.
|
||||
*/
|
||||
private String currentClan = "2009scape";
|
||||
|
||||
/**
|
||||
* The rank required for joining.
|
||||
*/
|
||||
private ClanRank joinRequirement = ClanRank.FRIEND;
|
||||
|
||||
/**
|
||||
* The rank required for messaging.
|
||||
*/
|
||||
private ClanRank messageRequirement = ClanRank.NONE;
|
||||
|
||||
/**
|
||||
* The rank required for kicking members.
|
||||
*/
|
||||
private ClanRank kickRequirement = ClanRank.OWNER;
|
||||
|
||||
/**
|
||||
* The rank required for loot-share.
|
||||
*/
|
||||
private ClanRank lootRequirement = ClanRank.ADMINISTRATOR;
|
||||
|
||||
/**
|
||||
* The public chat setting.
|
||||
*/
|
||||
private int publicChatSetting = 0;
|
||||
|
||||
/**
|
||||
* The private chat setting.
|
||||
*/
|
||||
private int privateChatSetting = 0;
|
||||
|
||||
/**
|
||||
* The trade setting.
|
||||
*/
|
||||
private int tradeSetting = 0;
|
||||
|
||||
/**
|
||||
* The player session.
|
||||
*/
|
||||
private PlayerSession player;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CommunicationInfo} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public CommunicationInfo(PlayerSession player) {
|
||||
this.setPlayer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the player logs in.
|
||||
*/
|
||||
public void sync() {
|
||||
if (privateChatSetting != 2) {
|
||||
for (GameServer server : WorldDatabase.getWorlds()) {
|
||||
if (server != null && server.isActive()) {
|
||||
List<String> names = new ArrayList<>(20);
|
||||
for (PlayerSession p : server.getPlayers().values()) {
|
||||
if (p.isActive() && p.getCommunication().contacts.containsKey(player.getUsername())) {
|
||||
if (privateChatSetting == 0 || contacts.containsKey(p.getUsername())) {
|
||||
names.add(p.getUsername());
|
||||
}
|
||||
}
|
||||
}
|
||||
WorldPacketRepository.notifyPlayers(server, player, names);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the player logs out.
|
||||
*/
|
||||
public void clear() {
|
||||
for (GameServer server : WorldDatabase.getWorlds()) {
|
||||
if (server != null && server.isActive()) {
|
||||
WorldPacketRepository.notifyLogout(server, player);
|
||||
}
|
||||
}
|
||||
if (player.getClan() != null) {
|
||||
player.getClan().leave(player, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the communication info.
|
||||
* @param statement The buffer.
|
||||
* @throws SQLException The exception if thrown.
|
||||
*/
|
||||
public void save(PreparedStatement statement) throws SQLException {
|
||||
String contacts = "";
|
||||
String blocked = "";
|
||||
StringBuilder blockedBuilder = new StringBuilder();
|
||||
for (int i = 0; i < this.blocked.size(); i++) {
|
||||
String blockline = (i == 0 ? "" : ",") + this.blocked.get(i);
|
||||
blockedBuilder.append(blockline);
|
||||
}
|
||||
blocked = blockedBuilder.toString();
|
||||
int count = 0;
|
||||
StringBuilder contactBuilder = new StringBuilder();
|
||||
for (Entry<String, ClanRank> entry : this.contacts.entrySet()) {
|
||||
String contactLine = "{" + entry.getKey() + "," + entry.getValue().ordinal() + "}" + (count == this.contacts.size() - 1 ? "" : "~");
|
||||
contactBuilder.append(contactLine);
|
||||
count++;
|
||||
}
|
||||
contacts = contactBuilder.toString();
|
||||
statement.setString(3, contacts);
|
||||
statement.setString(4, blocked);
|
||||
statement.setString(5, clanName);
|
||||
statement.setString(6, currentClan);
|
||||
statement.setString(7, joinRequirement.ordinal() + "," + messageRequirement.ordinal() + "," + kickRequirement.ordinal() + "," + lootRequirement.ordinal());
|
||||
statement.setString(8, publicChatSetting + "," + privateChatSetting + "," + tradeSetting);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the communication info from the database.
|
||||
* @param set The result set.
|
||||
* @throws SQLException The exception if thrown.
|
||||
*/
|
||||
public void parse(ResultSet set) throws SQLException {
|
||||
String contacts = set.getString("contacts");
|
||||
String[] tokens;
|
||||
if (contacts != null && !contacts.isEmpty()) {
|
||||
String[] datas = contacts.split("~");
|
||||
for (String d : datas) {
|
||||
tokens = d.replace("{", "").replace("}", "").split(",");
|
||||
if (tokens.length < 2) {
|
||||
continue;
|
||||
}
|
||||
this.contacts.put(tokens[0], ClanRank.values()[Integer.parseInt(tokens[1])]);
|
||||
}
|
||||
}
|
||||
String bl = set.getString("blocked");
|
||||
if (bl != null && !bl.isEmpty()) {
|
||||
tokens = bl.split(",");
|
||||
blocked.addAll(Arrays.asList(tokens));
|
||||
}
|
||||
clanName = set.getString("clanName");
|
||||
currentClan = set.getString("currentClan");
|
||||
String clanReqs = set.getString("clanReqs");
|
||||
if (!clanReqs.isEmpty()) {
|
||||
tokens = clanReqs.split(",");
|
||||
ClanRank rank = null;
|
||||
int ordinal = 0;
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
ordinal = Integer.parseInt(tokens[i]);
|
||||
if (ordinal < 0 || ordinal > ClanRank.values().length -1) {
|
||||
continue;
|
||||
}
|
||||
rank = ClanRank.values()[ordinal];
|
||||
switch (i) {
|
||||
case 0:
|
||||
joinRequirement = rank;
|
||||
break;
|
||||
case 1:
|
||||
messageRequirement = rank;
|
||||
break;
|
||||
case 2:
|
||||
if (ordinal < 3 || ordinal > 8) {
|
||||
break;
|
||||
}
|
||||
kickRequirement = rank;
|
||||
break;
|
||||
case 3:
|
||||
lootRequirement = rank;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
String chatSettings = set.getString("chatSettings");
|
||||
if (!chatSettings.isEmpty()) {
|
||||
tokens = chatSettings.split(",");
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
publicChatSetting = Integer.parseInt(tokens[0]);
|
||||
break;
|
||||
case 1:
|
||||
privateChatSetting = Integer.parseInt(tokens[1]);
|
||||
break;
|
||||
case 2:
|
||||
tradeSetting = Integer.parseInt(tokens[2]);
|
||||
break;
|
||||
default:
|
||||
System.out.println("Illegal arg count in chatsetting string: " + chatSettings);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the communication info.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
public void save(ByteBuffer buffer) {
|
||||
buffer.put((byte) contacts.size());
|
||||
for(Entry<String,ClanRank> contact : contacts.entrySet()){
|
||||
ByteBufferUtils.putString(contact.getKey(), buffer);
|
||||
buffer.put((byte) contact.getValue().ordinal());
|
||||
}
|
||||
buffer.put((byte) blocked.size());
|
||||
for (String name : blocked) {
|
||||
ByteBufferUtils.putString(name, buffer);
|
||||
}
|
||||
ByteBufferUtils.putString(clanName, buffer);
|
||||
if (currentClan != null) {
|
||||
ByteBufferUtils.putString(currentClan, buffer.put((byte) 1));
|
||||
} else {
|
||||
buffer.put((byte) 0);
|
||||
}
|
||||
buffer.put((byte) joinRequirement.ordinal());
|
||||
buffer.put((byte) messageRequirement.ordinal());
|
||||
buffer.put((byte) kickRequirement.ordinal());
|
||||
buffer.put((byte) lootRequirement.ordinal());
|
||||
buffer.put((byte) publicChatSetting);
|
||||
buffer.put((byte) privateChatSetting);
|
||||
buffer.put((byte) tradeSetting);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the communication info from the buffer.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
public void parse(ByteBuffer buffer) {
|
||||
int length = buffer.get() & 0xFF;
|
||||
for (int i = 0; i < length; i++) {
|
||||
contacts.put(ByteBufferUtils.getString(buffer), ClanRank.values()[buffer.get() & 0xFF]);
|
||||
}
|
||||
length = buffer.get() & 0xFF;
|
||||
for (int i = 0; i < length; i++) {
|
||||
blocked.add(ByteBufferUtils.getString(buffer));
|
||||
}
|
||||
clanName = ByteBufferUtils.getString(buffer);
|
||||
if (buffer.get() == 1) {
|
||||
currentClan = ByteBufferUtils.getString(buffer);
|
||||
}
|
||||
joinRequirement = ClanRank.values()[buffer.get()];
|
||||
messageRequirement = ClanRank.values()[buffer.get()];
|
||||
kickRequirement = ClanRank.values()[buffer.get()];
|
||||
lootRequirement = ClanRank.values()[buffer.get()];
|
||||
publicChatSetting = buffer.get();
|
||||
privateChatSetting = buffer.get();
|
||||
tradeSetting = buffer.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the target.
|
||||
* @param target The target.
|
||||
* @param message The message to send.
|
||||
*/
|
||||
public void sendMessage(String target, String message) {
|
||||
PlayerSession receiver = WorldDatabase.getPlayer(target);
|
||||
if (receiver == null || !receiver.isActive()) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "That player is currently offline.");
|
||||
return;
|
||||
}
|
||||
WorldPacketRepository.sendMessage(player, receiver, 0, message);
|
||||
WorldPacketRepository.sendMessage(receiver, player, 1, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a contact.
|
||||
* @param contact The contact to add.
|
||||
*/
|
||||
public void add(String contact) {
|
||||
if (contacts.size() >= MAX_LIST_SIZE) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "Your friend list is full.");
|
||||
return;
|
||||
}
|
||||
if (blocked.contains(contact)) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "Please remove " + StringUtils.formatDisplayName(contact) + " from your ignored list first.");
|
||||
return;
|
||||
}
|
||||
if (contacts.containsKey(contact)) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, StringUtils.formatDisplayName(contact) + " is already on your friend list.");
|
||||
return;
|
||||
}
|
||||
contacts.put(contact, ClanRank.FRIEND);
|
||||
WorldPacketRepository.sendContactUpdate(player, contact, false, false, getWorldId(player, contact), null);
|
||||
ClanRepository clan = ClanRepository.getClans().get(player.getUsername());
|
||||
if (clan != null) {
|
||||
clan.update();
|
||||
}
|
||||
if (privateChatSetting == 1) {
|
||||
PlayerSession other = WorldDatabase.getPlayer(contact);
|
||||
if (other != null && other.isActive() && other.getCommunication().getContacts().containsKey(player.getUsername())) {
|
||||
WorldPacketRepository.sendContactUpdate(other, player.getUsername(), false, false, getWorldId(other, player.getUsername()), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world id for the given contact.
|
||||
* @param player The player.
|
||||
* @param contact The contact.
|
||||
* @return The world id to display.
|
||||
*/
|
||||
public static int getWorldId(PlayerSession player, String contact) {
|
||||
PlayerSession p = WorldDatabase.getPlayer(contact);
|
||||
if (p == null || !p.isActive() || p.getCommunication().getPrivateChatSetting() == 2) {
|
||||
return 0;
|
||||
}
|
||||
if (p.getCommunication().getBlocked().contains(player.getUsername())) {
|
||||
return 0;
|
||||
}
|
||||
if (p.getCommunication().getPrivateChatSetting() == 1) {
|
||||
if (p.getCommunication().getContacts().containsKey(player.getUsername())) {
|
||||
return p.getWorldId();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return p.getWorldId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a contact.
|
||||
* @param contact The contact to remove.
|
||||
* @param block If the contact should be removed from the block list.
|
||||
*/
|
||||
public void remove(String contact, boolean block) {
|
||||
PlayerSession other = WorldDatabase.getPlayer(contact);
|
||||
if (block) {
|
||||
blocked.remove(contact);
|
||||
if (other != null && other.isActive() && other.getCommunication().getContacts().containsKey(player.getUsername())) {
|
||||
WorldPacketRepository.sendContactUpdate(other, player.getUsername(), false, false, getWorldId(other, player.getUsername()), null);
|
||||
}
|
||||
} else {
|
||||
contacts.remove(contact);
|
||||
ClanRepository clan = ClanRepository.getClans().get(player.getUsername());
|
||||
if (clan != null) {
|
||||
clan.update();
|
||||
}
|
||||
if (privateChatSetting == 1 && other != null && other.isActive() && other.getCommunication().getContacts().containsKey(player.getUsername())) {
|
||||
WorldPacketRepository.sendContactUpdate(other, player.getUsername(), false, false, getWorldId(other, player.getUsername()), null);
|
||||
}
|
||||
}
|
||||
WorldPacketRepository.sendContactUpdate(player, contact, block, true, 0, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a blocked contact.
|
||||
* @param contact The contact to block.
|
||||
*/
|
||||
public void block(String contact) {
|
||||
if (blocked.size() >= MAX_LIST_SIZE) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "Your ignore list is full.");
|
||||
return;
|
||||
}
|
||||
if (contacts.containsKey(contact)) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, "Please remove " + StringUtils.formatDisplayName(contact) + " from your friends list first.");
|
||||
return;
|
||||
}
|
||||
if (blocked.contains(contact)) {
|
||||
WorldPacketRepository.sendPlayerMessage(player, StringUtils.formatDisplayName(contact) + " is already on your friend list.");
|
||||
return;
|
||||
}
|
||||
blocked.add(contact);
|
||||
WorldPacketRepository.sendContactUpdate(player, contact, true, false, 0, null);
|
||||
PlayerSession other = WorldDatabase.getPlayer(contact);
|
||||
if (other != null && other.isActive() && other.getCommunication().getContacts().containsKey(player.getUsername())) {
|
||||
WorldPacketRepository.sendContactUpdate(other, player.getUsername(), false, false, 0, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the clan rank of a certain contact.
|
||||
* @param contact The contact.
|
||||
* @param clanRank The clan rank to set.
|
||||
*/
|
||||
public void updateClanRank(String contact, ClanRank clanRank) {
|
||||
if (!contacts.containsKey(contact)) {
|
||||
System.err.println("Could not find contact " + contact + " to update clan rank!");
|
||||
return;
|
||||
}
|
||||
contacts.put(contact, clanRank);
|
||||
ClanRepository clan = ClanRepository.getClans().get(player.getUsername());
|
||||
if (clan != null) {
|
||||
clan.update();
|
||||
}
|
||||
|
||||
WorldPacketRepository.sendContactUpdate(player, contact, false, false, 0, clanRank);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the settings.
|
||||
* @param publicSetting The public chat setting.
|
||||
* @param privateSetting The private chat setting.
|
||||
* @param tradeSetting The trade setting.
|
||||
*/
|
||||
public void updateSettings(int publicSetting, int privateSetting, int tradeSetting) {
|
||||
this.publicChatSetting = publicSetting;
|
||||
this.tradeSetting = tradeSetting;
|
||||
if (this.privateChatSetting != privateSetting) {
|
||||
updatePrivateSetting(privateSetting);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the private chat setting.
|
||||
* @param privateSetting The private chat setting.
|
||||
*/
|
||||
private void updatePrivateSetting(int privateSetting) {
|
||||
this.privateChatSetting = privateSetting;
|
||||
for (GameServer server : WorldDatabase.getWorlds()) {
|
||||
if (server != null && server.isActive()) {
|
||||
if (privateSetting == 2) {
|
||||
WorldPacketRepository.notifyLogout(server, player);
|
||||
continue;
|
||||
}
|
||||
for (PlayerSession p : server.getPlayers().values()) {
|
||||
if (p.isActive() && p.getCommunication().contacts.containsKey(player.getUsername())) {
|
||||
WorldPacketRepository.sendContactUpdate(p, player.getUsername(), false, false, getWorldId(p, player.getUsername()), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the contacts value.
|
||||
* @return The contacts.
|
||||
*/
|
||||
public Map<String, ClanRank> getContacts() {
|
||||
return contacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clan rank for the given contact.
|
||||
* @param contact The contact.
|
||||
* @return The rank.
|
||||
*/
|
||||
public ClanRank getRank(String contact) {
|
||||
return contacts.get(contact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the blocked value.
|
||||
* @return The blocked.
|
||||
*/
|
||||
public List<String> getBlocked() {
|
||||
return blocked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clanName value.
|
||||
* @return The clanName.
|
||||
*/
|
||||
public String getClanName() {
|
||||
return clanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the clanName value.
|
||||
* @param clanName The clanName to set.
|
||||
*/
|
||||
public void setClanName(String clanName) {
|
||||
this.clanName = clanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currentClan value.
|
||||
* @return The currentClan.
|
||||
*/
|
||||
public String getCurrentClan() {
|
||||
return currentClan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currentClan value.
|
||||
* @param currentClan The currentClan to set.
|
||||
*/
|
||||
public void setCurrentClan(String currentClan) {
|
||||
this.currentClan = currentClan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player value.
|
||||
* @return The player.
|
||||
*/
|
||||
public PlayerSession getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the player value.
|
||||
* @param player The player to set.
|
||||
*/
|
||||
public void setPlayer(PlayerSession player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the joinRequirement value.
|
||||
* @return The joinRequirement.
|
||||
*/
|
||||
public ClanRank getJoinRequirement() {
|
||||
return joinRequirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the joinRequirement value.
|
||||
* @param joinRequirement The joinRequirement to set.
|
||||
*/
|
||||
public void setJoinRequirement(ClanRank joinRequirement) {
|
||||
this.joinRequirement = joinRequirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the messageRequirement value.
|
||||
* @return The messageRequirement.
|
||||
*/
|
||||
public ClanRank getMessageRequirement() {
|
||||
return messageRequirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the messageRequirement value.
|
||||
* @param messageRequirement The messageRequirement to set.
|
||||
*/
|
||||
public void setMessageRequirement(ClanRank messageRequirement) {
|
||||
this.messageRequirement = messageRequirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the kickRequirement value.
|
||||
* @return The kickRequirement.
|
||||
*/
|
||||
public ClanRank getKickRequirement() {
|
||||
return kickRequirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the kickRequirement value.
|
||||
* @param kickRequirement The kickRequirement to set.
|
||||
*/
|
||||
public void setKickRequirement(ClanRank kickRequirement) {
|
||||
this.kickRequirement = kickRequirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lootRequirement value.
|
||||
* @return The lootRequirement.
|
||||
*/
|
||||
public ClanRank getLootRequirement() {
|
||||
return lootRequirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lootRequirement value.
|
||||
* @param lootRequirement The lootRequirement to set.
|
||||
*/
|
||||
public void setLootRequirement(ClanRank lootRequirement) {
|
||||
this.lootRequirement = lootRequirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the publicChatSetting value.
|
||||
* @return The publicChatSetting.
|
||||
*/
|
||||
public int getPublicChatSetting() {
|
||||
return publicChatSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the publicChatSetting value.
|
||||
* @param publicChatSetting The publicChatSetting to set.
|
||||
*/
|
||||
public void setPublicChatSetting(int publicChatSetting) {
|
||||
this.publicChatSetting = publicChatSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the privateChatSetting value.
|
||||
* @return The privateChatSetting.
|
||||
*/
|
||||
public int getPrivateChatSetting() {
|
||||
return privateChatSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the privateChatSetting value.
|
||||
* @param privateChatSetting The privateChatSetting to set.
|
||||
*/
|
||||
public void setPrivateChatSetting(int privateChatSetting) {
|
||||
this.privateChatSetting = privateChatSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tradeSetting value.
|
||||
* @return The tradeSetting.
|
||||
*/
|
||||
public int getTradeSetting() {
|
||||
return tradeSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tradeSetting value.
|
||||
* @param tradeSetting The tradeSetting to set.
|
||||
*/
|
||||
public void setTradeSetting(int tradeSetting) {
|
||||
this.tradeSetting = tradeSetting;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
package ms.system.mysql;
|
||||
|
||||
/**
|
||||
* Represents a column used in an SQL table.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class SQLColumn {
|
||||
|
||||
/**
|
||||
* The name.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The data type.
|
||||
*/
|
||||
private final Class<?> type;
|
||||
|
||||
/**
|
||||
* If this column should never be updated in the database.
|
||||
*/
|
||||
private final boolean neverUpdate;
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* If the column value changed.
|
||||
*/
|
||||
private boolean changed;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SQLColumn} {@code Object}.
|
||||
* @param name The column name.
|
||||
* @param type The data type.
|
||||
*/
|
||||
public SQLColumn(String name, Class<?> type) {
|
||||
this(name, type, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SQLColumn} {@code Object}.
|
||||
* @param name The column name.
|
||||
* @param type The data type.
|
||||
* @param neverUpdate If this column should never be updated in the database.
|
||||
*/
|
||||
public SQLColumn(String name, Class<?> type, boolean neverUpdate) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.neverUpdate = neverUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
* @return The name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the value.
|
||||
* @param value The value.
|
||||
*/
|
||||
public void updateValue(Object value) {
|
||||
this.changed = value != this.value;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value.
|
||||
* @return The value.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value.
|
||||
* @param value The value to set.
|
||||
*/
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
this.changed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the changed.
|
||||
* @return The changed.
|
||||
*/
|
||||
public boolean isChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the changed.
|
||||
* @param changed The changed to set.
|
||||
*/
|
||||
public void setChanged(boolean changed) {
|
||||
this.changed = changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
* @return The type.
|
||||
*/
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the neverUpdate.
|
||||
* @return The neverUpdate.
|
||||
*/
|
||||
public boolean isNeverUpdate() {
|
||||
return neverUpdate;
|
||||
}
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
package ms.system.mysql;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Handles an SQL entry.
|
||||
* @author Emperor
|
||||
* @param <T> The entry type.
|
||||
*/
|
||||
public abstract class SQLEntryHandler<T> {
|
||||
|
||||
/**
|
||||
* The connection.
|
||||
*/
|
||||
protected Connection connection;
|
||||
|
||||
/**
|
||||
* The entry.
|
||||
*/
|
||||
protected T entry;
|
||||
|
||||
/**
|
||||
* The result set.
|
||||
*/
|
||||
protected ResultSet result;
|
||||
|
||||
/**
|
||||
* The table name.
|
||||
*/
|
||||
protected String table;
|
||||
|
||||
/**
|
||||
* The column name.
|
||||
*/
|
||||
private String column;
|
||||
|
||||
/**
|
||||
* The value to use.
|
||||
*/
|
||||
protected String value;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SQLEntryHandler} {@code Object}.
|
||||
* @param entry The entry.
|
||||
* @param table The table name.
|
||||
* @param column column name.
|
||||
* @param value The column value.
|
||||
*/
|
||||
public SQLEntryHandler(T entry, String table, String column, String value) {
|
||||
this.entry = entry;
|
||||
this.table = table;
|
||||
this.column = column;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the SQL entry.
|
||||
* @param entry The entry.
|
||||
*/
|
||||
public static void read(SQLEntryHandler<?> entry) {
|
||||
entry.connection = entry.getConnection();
|
||||
if (entry.connection == null) {
|
||||
//System.err.println("Could not read SQL data: connection is null!");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
entry.read();
|
||||
if (entry.result == null || !entry.result.next()) {
|
||||
entry.create();
|
||||
} else {
|
||||
entry.parse();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SQLManager.close(entry.connection);
|
||||
entry.connection = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the entry data on the SQL database.
|
||||
* @param entry The entry.
|
||||
*/
|
||||
public static void write(SQLEntryHandler<?> entry) {
|
||||
write(entry, entry.getConnection(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the SQL entry.
|
||||
* @param entry The entry.
|
||||
*/
|
||||
public static void write(SQLEntryHandler<?> entry, Connection connection, boolean commit) {
|
||||
if (connection == null) {
|
||||
//System.err.println("Could not write SQL data: connection is null!");
|
||||
return;
|
||||
}
|
||||
entry.connection = connection;
|
||||
try {
|
||||
if (!commit) {
|
||||
entry.connection.setAutoCommit(false);
|
||||
}
|
||||
entry.save();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (commit) {
|
||||
SQLManager.close(entry.connection);
|
||||
}
|
||||
entry.connection = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the table from the SQL database.
|
||||
* @throws SQLException When an SQL exception occurs.
|
||||
*/
|
||||
public void read() throws SQLException {
|
||||
PreparedStatement statement = connection.prepareStatement("SELECT " + getReadSelection() + " FROM " + table + " WHERE " + column + " = ?");
|
||||
statement.setString(1, value);
|
||||
result = statement.executeQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the result.
|
||||
* @return the result.
|
||||
*/
|
||||
public ResultSet getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the selection.
|
||||
* @return The selection.
|
||||
*/
|
||||
public String getReadSelection() {
|
||||
return "*";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the writing statement.
|
||||
* @param create If we are creating a new row.
|
||||
* @param columns The columns to update.
|
||||
*/
|
||||
public PreparedStatement getWritingStatement(boolean create, String...columns) {
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (create) {
|
||||
sb.append("INSERT INTO ").append(table).append(" (").append(column);
|
||||
for (String name : columns) {
|
||||
sb.append(",").append(name);
|
||||
}
|
||||
sb.append(") VALUES (?");
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
sb.append(",?");
|
||||
}
|
||||
sb.append(")");
|
||||
} else {
|
||||
sb.append("UPDATE ").append(table).append(" SET ");
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
sb.append(columns[i]).append("=?");
|
||||
if (i < columns.length - 1) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
sb.append(" WHERE ").append(column).append("=?");
|
||||
}
|
||||
statement = connection.prepareStatement(sb.toString());
|
||||
statement.setString(create ? 1 : columns.length + 1, value);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the entry.
|
||||
* @throws SQLException When an SQL exception occurs.
|
||||
*/
|
||||
public abstract void parse() throws SQLException;
|
||||
|
||||
/**
|
||||
* Creates a new row in the database.
|
||||
* @throws SQLException When an SQL exception occurs.
|
||||
*/
|
||||
public abstract void create() throws SQLException;
|
||||
|
||||
/**
|
||||
* Saves the entry.
|
||||
* @throws SQLException When an SQL exception occurs.
|
||||
*/
|
||||
public abstract void save() throws SQLException;
|
||||
|
||||
/**
|
||||
* Gets the connection.
|
||||
* @return The connection.
|
||||
*/
|
||||
public abstract Connection getConnection();
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package ms.system.mysql
|
||||
|
||||
import ms.system.util.ManagementConstants
|
||||
import ms.system.util.ManagementConstants.DATABASE_HOST_ADDRESS
|
||||
import ms.system.util.ManagementConstants.DATABASE_NAME
|
||||
import ms.system.util.ManagementConstants.DATABASE_PASSWORD
|
||||
import ms.system.util.ManagementConstants.DATABASE_PORT
|
||||
import ms.system.util.ManagementConstants.DATABASE_USERNAME
|
||||
import java.sql.Connection
|
||||
import java.sql.DriverManager
|
||||
import java.sql.SQLException
|
||||
|
||||
/**
|
||||
* Manages the sql connections.
|
||||
* @author Vexia
|
||||
*/
|
||||
object SQLManager {
|
||||
|
||||
/**
|
||||
* IF the sql manager is initialized.
|
||||
*/
|
||||
var isInitialized = false
|
||||
|
||||
/**
|
||||
* Initializes the sql manager.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun init() {
|
||||
isInitialized = true
|
||||
WorldListSQLHandler.clearWorldList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a connection from the pool.
|
||||
* @return The connection.
|
||||
*/
|
||||
@JvmStatic
|
||||
val connection: Connection?
|
||||
get() {
|
||||
try {
|
||||
return DriverManager.getConnection(
|
||||
"jdbc:mysql://$DATABASE_HOST_ADDRESS:$DATABASE_PORT/$DATABASE_NAME?useTimezone=true&serverTimezone=UTC",
|
||||
DATABASE_USERNAME,
|
||||
DATABASE_PASSWORD
|
||||
)
|
||||
} catch (e: SQLException) {
|
||||
println("Error: Mysql error message=" + e.message + ".")
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the connection so it's available for usage.
|
||||
* @param connection The connection.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun close(connection: Connection) {
|
||||
try {
|
||||
connection.close()
|
||||
} catch (e: SQLException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package ms.system.mysql;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents an SQL table.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class SQLTable {
|
||||
|
||||
/**
|
||||
* The columns.
|
||||
*/
|
||||
private final SQLColumn[] columns;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SQLTable} {@code Object}.
|
||||
* @param columns The columns.
|
||||
*/
|
||||
public SQLTable(SQLColumn...columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column for the given name.
|
||||
* @param name The column name.
|
||||
* @return The column.
|
||||
*/
|
||||
public SQLColumn getColumn(String name) {
|
||||
for (SQLColumn column : columns) {
|
||||
if (column.getName().equals(name)) {
|
||||
return column;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the changed columns.
|
||||
* @return The columns.
|
||||
*/
|
||||
public List<SQLColumn> getChanged() {
|
||||
List<SQLColumn> updated = new ArrayList<>(20);
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
SQLColumn column = columns[i];
|
||||
if (column.isChanged()) {
|
||||
updated.add(column);
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package ms.system.mysql;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import ms.world.GameServer;
|
||||
import ms.world.info.WorldInfo;
|
||||
|
||||
/**
|
||||
* Handles the world list SQL database.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class WorldListSQLHandler extends SQLEntryHandler<GameServer> {
|
||||
|
||||
/**
|
||||
* The table for this sql entry.
|
||||
*/
|
||||
private static final String TABLE = "worlds";
|
||||
|
||||
/**
|
||||
* Constructs a new {@code WorldListSQLHandler} {@code Object}.
|
||||
* @param entry The game server entry.
|
||||
*/
|
||||
public WorldListSQLHandler(GameServer entry) {
|
||||
super(entry, TABLE, "world", "" + entry.getInfo().getWorldId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the world list.
|
||||
*/
|
||||
public static void clearWorldList() {
|
||||
Connection connection = SQLManager.getConnection();
|
||||
if(connection == null) return;
|
||||
try {
|
||||
PreparedStatement statement = connection.prepareStatement("DELETE FROM " + TABLE);
|
||||
statement.executeUpdate();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
SQLManager.close(connection);
|
||||
} finally {
|
||||
SQLManager.close(connection);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parse() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() throws SQLException {
|
||||
PreparedStatement statement = connection.prepareStatement("INSERT "+ table + "(world, ip, players, country, member, revision) VALUES('" + value + "', '" + entry.getInfo().getAddress() + "', '" + entry.getPlayerAmount() + "', '" + entry.getInfo().getCountry().getId() + "', '" + (entry.getInfo().isMembers() ? 1 : 0) + "', '" + entry.getInfo().getRevision() + "')");
|
||||
statement.executeUpdate();
|
||||
SQLManager.close(statement.getConnection());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws SQLException {
|
||||
super.read();
|
||||
if (result == null || !result.next()) {
|
||||
create();
|
||||
return;
|
||||
}
|
||||
int players = entry.getPlayerAmount();
|
||||
WorldInfo info = entry.getInfo();
|
||||
if (!entry.isActive()) {
|
||||
players = -1;
|
||||
}
|
||||
if (players <= 0) {
|
||||
PreparedStatement statement = connection.prepareStatement("UPDATE members SET online='0' WHERE lastWorld='" + value + "'");
|
||||
statement.executeUpdate();
|
||||
}
|
||||
PreparedStatement statement = connection.prepareStatement("UPDATE " + table + " SET players='" + players + "', ip='" + info.getAddress() + "', country='" + info.getCountry().getId() + "', member='" + (info.isMembers() ? 1 : 0) + "', revision='" + info.getRevision() + "' WHERE world='" + value + "'");
|
||||
statement.executeUpdate();
|
||||
SQLManager.close(statement.getConnection());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() {
|
||||
return SQLManager.getConnection();
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
package ms.system.util;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
|
||||
/**
|
||||
* Holds utility methods for reading/writing a byte buffer.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class ByteBufferUtils {
|
||||
|
||||
/**
|
||||
* Gets a string from the byte buffer.
|
||||
* @param buffer The byte buffer.
|
||||
* @return The string.
|
||||
*/
|
||||
public static String getString(ByteBuffer buffer) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte b;
|
||||
while ((b = buffer.get()) != 0) {
|
||||
sb.append((char) b);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a string on the byte buffer.
|
||||
* @param s The string to put.
|
||||
* @param buffer The byte buffer.
|
||||
*/
|
||||
public static void putString(String s, ByteBuffer buffer) {
|
||||
buffer.put(s.getBytes(StandardCharsets.UTF_8)).put((byte) 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string from the byte buffer.
|
||||
* @param s The string.
|
||||
* @param buffer The byte buffer.
|
||||
* @return The string.
|
||||
*/
|
||||
public static ByteBuffer putGJ2String(String s, ByteBuffer buffer) {
|
||||
byte[] packed = new byte[256];
|
||||
int length = packGJString2(0, packed, s);
|
||||
return buffer.put((byte) 0).put(packed, 0, length).put((byte) 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the XTEA encryption.
|
||||
* @param keys The keys.
|
||||
* @param start The start index.
|
||||
* @param end The end index.
|
||||
* @param buffer The byte buffer.
|
||||
*/
|
||||
public static void decodeXTEA(int[] keys, int start, int end, ByteBuffer buffer) {
|
||||
int l = buffer.position();
|
||||
buffer.position(start);
|
||||
int length = (end - start) / 8;
|
||||
for (int i = 0; i < length; i++) {
|
||||
int firstInt = buffer.getInt();
|
||||
int secondInt = buffer.getInt();
|
||||
int sum = 0xc6ef3720;
|
||||
int delta = 0x9e3779b9;
|
||||
for (int j = 32; j-- > 0;) {
|
||||
secondInt -= keys[(sum & 0x1c84) >>> 11] + sum ^ (firstInt >>> 5 ^ firstInt << 4) + firstInt;
|
||||
sum -= delta;
|
||||
firstInt -= (secondInt >>> 5 ^ secondInt << 4) + secondInt ^ keys[sum & 3] + sum;
|
||||
}
|
||||
buffer.position(buffer.position() - 8);
|
||||
buffer.putInt(firstInt);
|
||||
buffer.putInt(secondInt);
|
||||
}
|
||||
buffer.position(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a String to an Integer?
|
||||
*
|
||||
* @param position
|
||||
* The position.
|
||||
* @param buffer
|
||||
* The buffer used.
|
||||
* @param string
|
||||
* The String to convert.
|
||||
* @return The Integer.
|
||||
*/
|
||||
public static int packGJString2(int position, byte[] buffer, String string) {
|
||||
int length = string.length();
|
||||
int offset = position;
|
||||
for (int i = 0; length > i; i++) {
|
||||
int character = string.charAt(i);
|
||||
if (character > 127) {
|
||||
if (character > 2047) {
|
||||
buffer[offset++] = (byte) ((character | 919275) >> 12);
|
||||
buffer[offset++] = (byte) (128 | ((character >> 6) & 63));
|
||||
buffer[offset++] = (byte) (128 | (character & 63));
|
||||
} else {
|
||||
buffer[offset++] = (byte) ((character | 12309) >> 6);
|
||||
buffer[offset++] = (byte) (128 | (character & 63));
|
||||
}
|
||||
} else
|
||||
buffer[offset++] = (byte) character;
|
||||
}
|
||||
return offset - position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a tri-byte from the buffer.
|
||||
* @param buffer The buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
public static int getTriByte(ByteBuffer buffer) {
|
||||
return ((buffer.get() & 0xFF) << 16) + ((buffer.get() & 0xFF) << 8) + (buffer.get() & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a smart from the buffer.
|
||||
* @param buffer The buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
public static int getSmart(ByteBuffer buffer) {
|
||||
int peek = buffer.get() & 0xFF;
|
||||
if (peek <= Byte.MAX_VALUE) {
|
||||
return peek;
|
||||
}
|
||||
return ((peek << 8) | (buffer.get() & 0xFF)) - 32768;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a smart from the buffer.
|
||||
* @param buffer The buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
public static int getBigSmart(ByteBuffer buffer) {
|
||||
int value = 0;
|
||||
int current = getSmart(buffer);
|
||||
while (current == 32767) {
|
||||
current = getSmart(buffer);
|
||||
value += 32767;
|
||||
}
|
||||
value += current;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ByteBufferUtils} {@code Object}.
|
||||
*/
|
||||
private ByteBufferUtils() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package ms.system.util;
|
||||
|
||||
/**
|
||||
* Represents a command.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public abstract class Command {
|
||||
|
||||
/**
|
||||
* The command name.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The command info.
|
||||
*/
|
||||
private final String info;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Command} {@code Object}.
|
||||
* @param name The command name.
|
||||
* @param info The command info.
|
||||
*/
|
||||
public Command(String name, String info) {
|
||||
this.name = name;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command.
|
||||
* @param args The arguments.
|
||||
*/
|
||||
public abstract void run(String...args);
|
||||
|
||||
/**
|
||||
* Gets the name value.
|
||||
* @return The name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the info value.
|
||||
* @return The info.
|
||||
*/
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,815 +0,0 @@
|
||||
package ms.system.util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* Represents the class of simple encryption functions.
|
||||
* @author Unknown
|
||||
*/
|
||||
public class EncryptionManager {
|
||||
|
||||
// Define the BCrypt workload to use when generating password hashes. 10-31 is a valid value.
|
||||
private static int workload = 12;
|
||||
|
||||
/**
|
||||
* Singleton instance.
|
||||
*/
|
||||
private static final EncryptionManager INSTANCE = new EncryptionManager();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code EncryptionManager} {@code Object}.
|
||||
*/
|
||||
private EncryptionManager() {
|
||||
//empty.
|
||||
}
|
||||
|
||||
/**
|
||||
* This method can be used to generate a string representing an account password
|
||||
* suitable for storing in a database. It will be an OpenBSD-style crypt(3) formatted
|
||||
* hash string of length=60
|
||||
* The bcrypt workload is specified in the above static variable, a value from 10 to 31.
|
||||
* A workload of 12 is a very reasonable safe default as of 2013.
|
||||
* This automatically handles secure 128-bit salt generation and storage within the hash.
|
||||
* @param password_plaintext The account's plaintext password as provided during account creation,
|
||||
* or when changing an account's password.
|
||||
* @return String - a string of length 60 that is the bcrypt hashed password in crypt(3) format.
|
||||
*/
|
||||
public String hashPassword(String password_plaintext) {
|
||||
String salt = BCrypt.gensalt(workload);
|
||||
String hashed_password = BCrypt.hashpw(password_plaintext, salt);
|
||||
return(hashed_password);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method can be used to verify a computed hash from a plaintext (e.g. during a login
|
||||
* request) with that of a stored hash from a database. The password hash from the database
|
||||
* must be passed as the second variable.
|
||||
* @param password_plaintext The account's plaintext password, as provided during a login request
|
||||
* @param stored_hash The account's stored password hash, retrieved from the authorization database
|
||||
* @return boolean - true if the password matches the password of the stored hash, false otherwise
|
||||
*/
|
||||
public boolean checkPassword(String password_plaintext, String stored_hash) {
|
||||
boolean password_verified = false;
|
||||
if(null == stored_hash || !stored_hash.startsWith("$2a$"))
|
||||
throw new java.lang.IllegalArgumentException("Invalid hash provided for comparison");
|
||||
password_verified = BCrypt.checkpw(password_plaintext, stored_hash);
|
||||
return(password_verified);
|
||||
}
|
||||
|
||||
// Copyright (c) 2006 Damien Miller <djm@mindrot.org>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
/**
|
||||
* Gets the instance value.
|
||||
* @return The instance.
|
||||
*/
|
||||
public static EncryptionManager getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* BCrypt implements OpenBSD-style Blowfish password hashing using
|
||||
* the scheme described in "A Future-Adaptable Password Scheme" by
|
||||
* Niels Provos and David Mazieres.
|
||||
* <p>
|
||||
* This password hashing system tries to thwart off-line password
|
||||
* cracking using a computationally-intensive hashing algorithm,
|
||||
* based on Bruce Schneier's Blowfish cipher. The work factor of
|
||||
* the algorithm is parameterised, so it can be increased as
|
||||
* computers get faster.
|
||||
* <p>
|
||||
* Usage is really simple. To hash a password for the first time,
|
||||
* call the hashpw method with a random salt, like this:
|
||||
* <p>
|
||||
* <code>
|
||||
* String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt()); <br />
|
||||
* </code>
|
||||
* <p>
|
||||
* To check whether a plaintext password matches one that has been
|
||||
* hashed previously, use the checkpw method:
|
||||
* <p>
|
||||
* <code>
|
||||
* if (BCrypt.checkpw(candidate_password, stored_hash))<br />
|
||||
* System.out.println("It matches");<br />
|
||||
* else<br />
|
||||
* System.out.println("It does not match");<br />
|
||||
* </code>
|
||||
* <p>
|
||||
* The gensalt() method takes an optional parameter (log_rounds)
|
||||
* that determines the computational complexity of the hashing:
|
||||
* <p>
|
||||
* <code>
|
||||
* String strong_salt = BCrypt.gensalt(10)<br />
|
||||
* String stronger_salt = BCrypt.gensalt(12)<br />
|
||||
* </code>
|
||||
* <p>
|
||||
* The amount of work increases exponentially (2**log_rounds), so
|
||||
* each increment is twice as much work. The default log_rounds is
|
||||
* 10, and the valid range is 4 to 31.
|
||||
*
|
||||
* @author Damien Miller
|
||||
* @version 0.2
|
||||
*/
|
||||
public static class BCrypt {
|
||||
// BCrypt parameters
|
||||
private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10;
|
||||
private static final int BCRYPT_SALT_LEN = 16;
|
||||
|
||||
// Blowfish parameters
|
||||
private static final int BLOWFISH_NUM_ROUNDS = 16;
|
||||
|
||||
// Initial contents of key schedule
|
||||
private static final int P_orig[] = {
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
|
||||
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
||||
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
||||
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
||||
0x9216d5d9, 0x8979fb1b
|
||||
};
|
||||
private static final int S_orig[] = {
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
|
||||
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
||||
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
||||
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
||||
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
|
||||
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
|
||||
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
|
||||
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
||||
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
|
||||
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
|
||||
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
||||
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
|
||||
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
|
||||
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
||||
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
|
||||
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
|
||||
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
|
||||
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
|
||||
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
||||
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
|
||||
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
|
||||
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
||||
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
|
||||
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
|
||||
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
||||
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
|
||||
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
|
||||
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
||||
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
|
||||
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
|
||||
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
||||
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
|
||||
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
|
||||
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
|
||||
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
|
||||
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
||||
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
|
||||
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
|
||||
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
||||
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
|
||||
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
|
||||
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
||||
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
|
||||
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
|
||||
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
||||
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
|
||||
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
|
||||
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
||||
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
|
||||
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
|
||||
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
|
||||
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
|
||||
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
||||
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
|
||||
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
|
||||
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
||||
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
|
||||
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
|
||||
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
||||
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
|
||||
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
|
||||
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
||||
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
|
||||
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
|
||||
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
|
||||
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
||||
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
|
||||
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
||||
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
|
||||
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
|
||||
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
|
||||
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
||||
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
|
||||
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
||||
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
|
||||
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
|
||||
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
|
||||
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
|
||||
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
||||
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
|
||||
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
|
||||
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
|
||||
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
||||
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
|
||||
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
||||
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
|
||||
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
|
||||
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
|
||||
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
||||
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
|
||||
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
||||
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
|
||||
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
|
||||
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
|
||||
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
|
||||
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
||||
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
|
||||
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
|
||||
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
|
||||
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
||||
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
|
||||
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
||||
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
|
||||
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
|
||||
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
|
||||
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
||||
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
|
||||
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
||||
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
|
||||
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
|
||||
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
|
||||
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
|
||||
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
||||
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
|
||||
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
|
||||
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
|
||||
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
||||
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
|
||||
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
||||
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
|
||||
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
|
||||
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
|
||||
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
|
||||
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
|
||||
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
||||
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
|
||||
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
||||
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
|
||||
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
|
||||
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
|
||||
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
||||
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
|
||||
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
||||
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
|
||||
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
|
||||
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
|
||||
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
||||
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
|
||||
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
|
||||
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
|
||||
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
|
||||
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
||||
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
|
||||
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
||||
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
|
||||
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
|
||||
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
|
||||
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
||||
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
|
||||
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
||||
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
|
||||
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
|
||||
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
|
||||
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
||||
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
|
||||
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
|
||||
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
|
||||
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
|
||||
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
||||
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
|
||||
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
||||
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
|
||||
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
|
||||
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
|
||||
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
||||
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
|
||||
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
||||
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
|
||||
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
|
||||
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
|
||||
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
||||
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
|
||||
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
|
||||
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
|
||||
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
|
||||
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
||||
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
|
||||
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
||||
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
|
||||
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
|
||||
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
|
||||
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
|
||||
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
|
||||
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
|
||||
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
||||
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
|
||||
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
|
||||
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
||||
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
|
||||
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
|
||||
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
||||
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
|
||||
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
|
||||
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
||||
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
|
||||
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
|
||||
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
||||
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
|
||||
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
|
||||
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
|
||||
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
|
||||
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
||||
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
|
||||
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
|
||||
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
||||
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
|
||||
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
|
||||
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
||||
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
|
||||
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
|
||||
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
||||
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
|
||||
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
|
||||
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
||||
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
|
||||
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
|
||||
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
|
||||
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
|
||||
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
||||
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
|
||||
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
|
||||
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
||||
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
|
||||
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
|
||||
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
||||
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
|
||||
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
|
||||
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
||||
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
|
||||
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
|
||||
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
||||
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
|
||||
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
|
||||
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
|
||||
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
|
||||
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
||||
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
|
||||
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
|
||||
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
||||
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
|
||||
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
|
||||
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
||||
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
|
||||
};
|
||||
|
||||
// bcrypt IV: "OrpheanBeholderScryDoubt"
|
||||
static private final int bf_crypt_ciphertext[] = {
|
||||
0x4f727068, 0x65616e42, 0x65686f6c,
|
||||
0x64657253, 0x63727944, 0x6f756274
|
||||
};
|
||||
|
||||
// Table for Base64 encoding
|
||||
static private final char base64_code[] = {
|
||||
'.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
|
||||
'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
|
||||
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
|
||||
'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
|
||||
'6', '7', '8', '9'
|
||||
};
|
||||
|
||||
// Table for Base64 decoding
|
||||
static private final byte index_64[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, 0, 1, 54, 55,
|
||||
56, 57, 58, 59, 60, 61, 62, 63, -1, -1,
|
||||
-1, -1, -1, -1, -1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
|
||||
-1, -1, -1, -1, -1, -1, 28, 29, 30,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
|
||||
51, 52, 53, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
// Expanded Blowfish key
|
||||
private int P[];
|
||||
private int S[];
|
||||
|
||||
/**
|
||||
* Encode a byte array using bcrypt's slightly-modified base64
|
||||
* encoding scheme. Note that this is *not* compatible with
|
||||
* the standard MIME-base64 encoding.
|
||||
*
|
||||
* @param d the byte array to encode
|
||||
* @param len the number of bytes to encode
|
||||
* @return base64-encoded string
|
||||
* @exception IllegalArgumentException if the length is invalid
|
||||
*/
|
||||
private static String encode_base64(byte d[], int len)
|
||||
throws IllegalArgumentException {
|
||||
int off = 0;
|
||||
StringBuffer rs = new StringBuffer();
|
||||
int c1, c2;
|
||||
|
||||
if (len <= 0 || len > d.length)
|
||||
throw new IllegalArgumentException ("Invalid len");
|
||||
|
||||
while (off < len) {
|
||||
c1 = d[off++] & 0xff;
|
||||
rs.append(base64_code[(c1 >> 2) & 0x3f]);
|
||||
c1 = (c1 & 0x03) << 4;
|
||||
if (off >= len) {
|
||||
rs.append(base64_code[c1 & 0x3f]);
|
||||
break;
|
||||
}
|
||||
c2 = d[off++] & 0xff;
|
||||
c1 |= (c2 >> 4) & 0x0f;
|
||||
rs.append(base64_code[c1 & 0x3f]);
|
||||
c1 = (c2 & 0x0f) << 2;
|
||||
if (off >= len) {
|
||||
rs.append(base64_code[c1 & 0x3f]);
|
||||
break;
|
||||
}
|
||||
c2 = d[off++] & 0xff;
|
||||
c1 |= (c2 >> 6) & 0x03;
|
||||
rs.append(base64_code[c1 & 0x3f]);
|
||||
rs.append(base64_code[c2 & 0x3f]);
|
||||
}
|
||||
return rs.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up the 3 bits base64-encoded by the specified character,
|
||||
* range-checking againt conversion table
|
||||
* @param x the base64-encoded value
|
||||
* @return the decoded value of x
|
||||
*/
|
||||
private static byte char64(char x) {
|
||||
if ((int)x > index_64.length)
|
||||
return -1;
|
||||
return index_64[(int)x];
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a string encoded using bcrypt's base64 scheme to a
|
||||
* byte array. Note that this is *not* compatible with
|
||||
* the standard MIME-base64 encoding.
|
||||
* @param s the string to decode
|
||||
* @param maxolen the maximum number of bytes to decode
|
||||
* @return an array containing the decoded bytes
|
||||
* @throws IllegalArgumentException if maxolen is invalid
|
||||
*/
|
||||
private static byte[] decode_base64(String s, int maxolen)
|
||||
throws IllegalArgumentException {
|
||||
StringBuffer rs = new StringBuffer();
|
||||
int off = 0, slen = s.length(), olen = 0;
|
||||
byte ret[];
|
||||
byte c1, c2, c3, c4, o;
|
||||
|
||||
if (maxolen <= 0)
|
||||
throw new IllegalArgumentException ("Invalid maxolen");
|
||||
|
||||
while (off < slen - 1 && olen < maxolen) {
|
||||
c1 = char64(s.charAt(off++));
|
||||
c2 = char64(s.charAt(off++));
|
||||
if (c1 == -1 || c2 == -1)
|
||||
break;
|
||||
o = (byte)(c1 << 2);
|
||||
o |= (c2 & 0x30) >> 4;
|
||||
rs.append((char)o);
|
||||
if (++olen >= maxolen || off >= slen)
|
||||
break;
|
||||
c3 = char64(s.charAt(off++));
|
||||
if (c3 == -1)
|
||||
break;
|
||||
o = (byte)((c2 & 0x0f) << 4);
|
||||
o |= (c3 & 0x3c) >> 2;
|
||||
rs.append((char)o);
|
||||
if (++olen >= maxolen || off >= slen)
|
||||
break;
|
||||
c4 = char64(s.charAt(off++));
|
||||
o = (byte)((c3 & 0x03) << 6);
|
||||
o |= c4;
|
||||
rs.append((char)o);
|
||||
++olen;
|
||||
}
|
||||
|
||||
ret = new byte[olen];
|
||||
for (off = 0; off < olen; off++)
|
||||
ret[off] = (byte)rs.charAt(off);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blowfish encipher a single 64-bit block encoded as
|
||||
* two 32-bit halves
|
||||
* @param lr an array containing the two 32-bit half blocks
|
||||
* @param off the position in the array of the blocks
|
||||
*/
|
||||
private final void encipher(int lr[], int off) {
|
||||
int i, n, l = lr[off], r = lr[off + 1];
|
||||
|
||||
l ^= P[0];
|
||||
for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) {
|
||||
// Feistel substitution on left word
|
||||
n = S[(l >> 24) & 0xff];
|
||||
n += S[0x100 | ((l >> 16) & 0xff)];
|
||||
n ^= S[0x200 | ((l >> 8) & 0xff)];
|
||||
n += S[0x300 | (l & 0xff)];
|
||||
r ^= n ^ P[++i];
|
||||
|
||||
// Feistel substitution on right word
|
||||
n = S[(r >> 24) & 0xff];
|
||||
n += S[0x100 | ((r >> 16) & 0xff)];
|
||||
n ^= S[0x200 | ((r >> 8) & 0xff)];
|
||||
n += S[0x300 | (r & 0xff)];
|
||||
l ^= n ^ P[++i];
|
||||
}
|
||||
lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1];
|
||||
lr[off + 1] = l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cycically extract a word of key material
|
||||
* @param data the string to extract the data from
|
||||
* @param offp a "pointer" (as a one-entry array) to the
|
||||
* current offset into data
|
||||
* @return the next word of material from data
|
||||
*/
|
||||
private static int streamtoword(byte data[], int offp[]) {
|
||||
int i;
|
||||
int word = 0;
|
||||
int off = offp[0];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
word = (word << 8) | (data[off] & 0xff);
|
||||
off = (off + 1) % data.length;
|
||||
}
|
||||
|
||||
offp[0] = off;
|
||||
return word;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the Blowfish key schedule
|
||||
*/
|
||||
private void init_key() {
|
||||
P = (int[])P_orig.clone();
|
||||
S = (int[])S_orig.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Key the Blowfish cipher
|
||||
* @param key an array containing the key
|
||||
*/
|
||||
private void key(byte key[]) {
|
||||
int i;
|
||||
int koffp[] = { 0 };
|
||||
int lr[] = { 0, 0 };
|
||||
int plen = P.length, slen = S.length;
|
||||
|
||||
for (i = 0; i < plen; i++)
|
||||
P[i] = P[i] ^ streamtoword(key, koffp);
|
||||
|
||||
for (i = 0; i < plen; i += 2) {
|
||||
encipher(lr, 0);
|
||||
P[i] = lr[0];
|
||||
P[i + 1] = lr[1];
|
||||
}
|
||||
|
||||
for (i = 0; i < slen; i += 2) {
|
||||
encipher(lr, 0);
|
||||
S[i] = lr[0];
|
||||
S[i + 1] = lr[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the "enhanced key schedule" step described by
|
||||
* Provos and Mazieres in "A Future-Adaptable Password Scheme"
|
||||
* http://www.openbsd.org/papers/bcrypt-paper.ps
|
||||
* @param data salt information
|
||||
* @param key password information
|
||||
*/
|
||||
private void ekskey(byte data[], byte key[]) {
|
||||
int i;
|
||||
int koffp[] = { 0 }, doffp[] = { 0 };
|
||||
int lr[] = { 0, 0 };
|
||||
int plen = P.length, slen = S.length;
|
||||
|
||||
for (i = 0; i < plen; i++)
|
||||
P[i] = P[i] ^ streamtoword(key, koffp);
|
||||
|
||||
for (i = 0; i < plen; i += 2) {
|
||||
lr[0] ^= streamtoword(data, doffp);
|
||||
lr[1] ^= streamtoword(data, doffp);
|
||||
encipher(lr, 0);
|
||||
P[i] = lr[0];
|
||||
P[i + 1] = lr[1];
|
||||
}
|
||||
|
||||
for (i = 0; i < slen; i += 2) {
|
||||
lr[0] ^= streamtoword(data, doffp);
|
||||
lr[1] ^= streamtoword(data, doffp);
|
||||
encipher(lr, 0);
|
||||
S[i] = lr[0];
|
||||
S[i + 1] = lr[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the central password hashing step in the
|
||||
* bcrypt scheme
|
||||
* @param password the password to hash
|
||||
* @param salt the binary salt to hash with the password
|
||||
* @param log_rounds the binary logarithm of the number
|
||||
* of rounds of hashing to apply
|
||||
* @return an array containing the binary hashed password
|
||||
*/
|
||||
private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) {
|
||||
int rounds, i, j;
|
||||
int cdata[] = (int[])bf_crypt_ciphertext.clone();
|
||||
int clen = cdata.length;
|
||||
byte ret[];
|
||||
|
||||
if (log_rounds < 4 || log_rounds > 31)
|
||||
throw new IllegalArgumentException ("Bad number of rounds");
|
||||
rounds = 1 << log_rounds;
|
||||
if (salt.length != BCRYPT_SALT_LEN)
|
||||
throw new IllegalArgumentException ("Bad salt length");
|
||||
|
||||
init_key();
|
||||
ekskey(salt, password);
|
||||
for (i = 0; i < rounds; i++) {
|
||||
key(password);
|
||||
key(salt);
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
for (j = 0; j < (clen >> 1); j++)
|
||||
encipher(cdata, j << 1);
|
||||
}
|
||||
|
||||
ret = new byte[clen * 4];
|
||||
for (i = 0, j = 0; i < clen; i++) {
|
||||
ret[j++] = (byte)((cdata[i] >> 24) & 0xff);
|
||||
ret[j++] = (byte)((cdata[i] >> 16) & 0xff);
|
||||
ret[j++] = (byte)((cdata[i] >> 8) & 0xff);
|
||||
ret[j++] = (byte)(cdata[i] & 0xff);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash a password using the OpenBSD bcrypt scheme
|
||||
* @param password the password to hash
|
||||
* @param salt the salt to hash with (perhaps generated
|
||||
* using BCrypt.gensalt)
|
||||
* @return the hashed password
|
||||
*/
|
||||
public static String hashpw(String password, String salt) {
|
||||
BCrypt B;
|
||||
String real_salt;
|
||||
byte passwordb[], saltb[], hashed[];
|
||||
char minor = (char)0;
|
||||
int rounds, off = 0;
|
||||
StringBuffer rs = new StringBuffer();
|
||||
|
||||
if (salt.charAt(0) != '$' || salt.charAt(1) != '2')
|
||||
throw new IllegalArgumentException ("Invalid salt version");
|
||||
if (salt.charAt(2) == '$')
|
||||
off = 3;
|
||||
else {
|
||||
minor = salt.charAt(2);
|
||||
if (minor != 'a' || salt.charAt(3) != '$')
|
||||
throw new IllegalArgumentException ("Invalid salt revision");
|
||||
off = 4;
|
||||
}
|
||||
|
||||
// Extract number of rounds
|
||||
if (salt.charAt(off + 2) > '$')
|
||||
throw new IllegalArgumentException ("Missing salt rounds");
|
||||
rounds = Integer.parseInt(salt.substring(off, off + 2));
|
||||
|
||||
real_salt = salt.substring(off + 3, off + 25);
|
||||
try {
|
||||
passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException uee) {
|
||||
throw new AssertionError("UTF-8 is not supported");
|
||||
}
|
||||
|
||||
saltb = decode_base64(real_salt, BCRYPT_SALT_LEN);
|
||||
|
||||
B = new BCrypt();
|
||||
hashed = B.crypt_raw(passwordb, saltb, rounds);
|
||||
|
||||
rs.append("$2");
|
||||
if (minor >= 'a')
|
||||
rs.append(minor);
|
||||
rs.append("$");
|
||||
if (rounds < 10)
|
||||
rs.append("0");
|
||||
rs.append(Integer.toString(rounds));
|
||||
rs.append("$");
|
||||
rs.append(encode_base64(saltb, saltb.length));
|
||||
rs.append(encode_base64(hashed,
|
||||
bf_crypt_ciphertext.length * 4 - 1));
|
||||
return rs.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a salt for use with the BCrypt.hashpw() method
|
||||
* @param log_rounds the log2 of the number of rounds of
|
||||
* hashing to apply - the work factor therefore increases as
|
||||
* 2**log_rounds.
|
||||
* @param random an instance of SecureRandom to use
|
||||
* @return an encoded salt value
|
||||
*/
|
||||
public static String gensalt(int log_rounds, SecureRandom random) {
|
||||
StringBuffer rs = new StringBuffer();
|
||||
byte rnd[] = new byte[BCRYPT_SALT_LEN];
|
||||
|
||||
random.nextBytes(rnd);
|
||||
|
||||
rs.append("$2a$");
|
||||
if (log_rounds < 10)
|
||||
rs.append("0");
|
||||
rs.append(Integer.toString(log_rounds));
|
||||
rs.append("$");
|
||||
rs.append(encode_base64(rnd, rnd.length));
|
||||
return rs.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a salt for use with the BCrypt.hashpw() method
|
||||
* @param log_rounds the log2 of the number of rounds of
|
||||
* hashing to apply - the work factor therefore increases as
|
||||
* 2**log_rounds.
|
||||
* @return an encoded salt value
|
||||
*/
|
||||
public static String gensalt(int log_rounds) {
|
||||
return gensalt(log_rounds, new SecureRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a salt for use with the BCrypt.hashpw() method,
|
||||
* selecting a reasonable default for the number of hashing
|
||||
* rounds to apply
|
||||
* @return an encoded salt value
|
||||
*/
|
||||
public static String gensalt() {
|
||||
return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a plaintext password matches a previously hashed
|
||||
* one
|
||||
* @param plaintext the plaintext password to verify
|
||||
* @param hashed the previously-hashed password
|
||||
* @return true if the passwords match, false otherwise
|
||||
*/
|
||||
public static boolean checkpw(String plaintext, String hashed) {
|
||||
return (hashed.compareTo(hashpw(plaintext, hashed)) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package ms.system.util
|
||||
|
||||
import org.json.simple.JSONObject
|
||||
import org.json.simple.parser.JSONParser
|
||||
import java.io.File
|
||||
import java.io.FileReader
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
/**
|
||||
* Class for parsing the server config, I.E default.conf
|
||||
* @param path the path to the JSON file to parse.
|
||||
* @author Ceikry
|
||||
*/
|
||||
class ManagementConfigParser(path: String) {
|
||||
val pathTo = parsePath(path)
|
||||
val confFile = File(pathTo)
|
||||
val parser = JSONParser()
|
||||
var reader: FileReader? = null
|
||||
var data: JSONObject? = null
|
||||
|
||||
init {
|
||||
if(!confFile.canonicalFile.exists()){
|
||||
println("Could not find ${confFile.canonicalFile} - Double check your working directory!")
|
||||
exitProcess(0)
|
||||
} else if(!pathTo.contains(".json")) {
|
||||
println("Config file MUST be a JSON file!!")
|
||||
println("(Got $pathTo)")
|
||||
} else {
|
||||
reader = FileReader(pathTo)
|
||||
data = parser.parse(reader) as JSONObject
|
||||
parseDatabaseInformation()
|
||||
parseWorldTechnicalSettings()
|
||||
ManagementConstants.SECRET_KEY = data!!["secret_key"].toString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseDatabaseInformation(){
|
||||
data ?: return
|
||||
val dbData = data!!["DatabaseInformation"] as JSONObject
|
||||
ManagementConstants.parseDBProp(dbData)
|
||||
}
|
||||
|
||||
private fun parseWorldTechnicalSettings(){
|
||||
data ?: return
|
||||
val wtiData = data!!["WorldTechnicalInformation"] as JSONObject
|
||||
ManagementConstants.parseWTIProp(wtiData)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a path string
|
||||
* @author Ceikry
|
||||
* @param pathString The string to parse
|
||||
* @return a String with the proper file separators for the current OS.
|
||||
*/
|
||||
fun parsePath(pathString: String): String {
|
||||
var pathTokens: List<String>? = null
|
||||
if(pathString.contains("/"))
|
||||
pathTokens = pathString.split("/")
|
||||
else if(pathString.contains("\\"))
|
||||
pathTokens = pathString.split("\\")
|
||||
|
||||
pathTokens ?: return pathString //return the initial pathString if path does not contain file separators.
|
||||
var pathProduct = ""
|
||||
for(token in pathTokens){
|
||||
if(token != "")
|
||||
pathProduct += "$token${File.separator}"
|
||||
}
|
||||
|
||||
return pathProduct
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package ms.system.util
|
||||
|
||||
import org.json.simple.JSONObject
|
||||
|
||||
object ManagementConstants {
|
||||
|
||||
//MySQL main database name
|
||||
var DATABASE_NAME: String = "global"
|
||||
|
||||
//MySQL database username
|
||||
var DATABASE_USERNAME: String = "root"
|
||||
|
||||
//MySQL database password
|
||||
var DATABASE_PASSWORD: String = ""
|
||||
|
||||
//MySQL host
|
||||
var DATABASE_HOST_ADDRESS: String = "127.0.0.1"
|
||||
|
||||
//MySQL port
|
||||
var DATABASE_PORT: Int = 3306
|
||||
|
||||
//Max amount of worlds supported on the world list
|
||||
var MAX_WORLD_AMOUNT: Int = 10
|
||||
|
||||
//User world hop delay in seconds
|
||||
var WORLD_HOP_DELAY: Long = 20_000L
|
||||
|
||||
@JvmStatic
|
||||
var SECRET_KEY: String = ""
|
||||
|
||||
fun parseDBProp(data: JSONObject) {
|
||||
DATABASE_NAME = data["database_name"].toString()
|
||||
DATABASE_USERNAME = data["database_username"].toString()
|
||||
DATABASE_PASSWORD = data["database_password"].toString()
|
||||
DATABASE_HOST_ADDRESS = data["database_host"].toString()
|
||||
DATABASE_PORT = data["database_port"].toString().toInt()
|
||||
}
|
||||
|
||||
fun parseWTIProp(data: JSONObject) {
|
||||
MAX_WORLD_AMOUNT = data["world_limit"].toString().toInt()
|
||||
WORLD_HOP_DELAY = data["worldhop_delay"].toString().toLong()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package ms.system.util;
|
||||
|
||||
/**
|
||||
* Handles generating a player database.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class PlayerDatabaseGen {
|
||||
|
||||
/**
|
||||
* The main method.
|
||||
* @param args The arguments.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,640 +0,0 @@
|
||||
package ms.system.util;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import ms.net.packet.IoBuffer;
|
||||
|
||||
/**
|
||||
* The string utils.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class StringUtils {
|
||||
|
||||
/**
|
||||
* The valid characters to be used in names/messages/...
|
||||
*/
|
||||
private static final char[] VALID_CHARS = {
|
||||
'_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
|
||||
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
|
||||
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
|
||||
};
|
||||
/**
|
||||
* The an int array241.
|
||||
*/
|
||||
private final static int[] anIntArray241 = { 215, 203, 83, 158, 104, 101, 93, 84,
|
||||
107, 103, 109, 95, 94, 98, 89, 86, 70, 41, 32, 27, 24, 23, -1, -2,
|
||||
26, -3, -4, 31, 30, -5, -6, -7, 37, 38, 36, -8, -9, -10, 40, -11,
|
||||
-12, 55, 48, 46, 47, -13, -14, -15, 52, 51, -16, -17, 54, -18, -19,
|
||||
63, 60, 59, -20, -21, 62, -22, -23, 67, 66, -24, -25, 69, -26, -27,
|
||||
199, 132, 80, 77, 76, -28, -29, 79, -30, -31, 87, 85, -32, -33,
|
||||
-34, -35, -36, 197, -37, 91, -38, 134, -39, -40, -41, 97, -42, -43,
|
||||
133, 106, -44, 117, -45, -46, 139, -47, -48, 110, -49, -50, 114,
|
||||
113, -51, -52, 116, -53, -54, 135, 138, 136, 129, 125, 124, -55,
|
||||
-56, 130, 128, -57, -58, -59, 183, -60, -61, -62, -63, -64, 148,
|
||||
-65, -66, 153, 149, 145, 144, -67, -68, 147, -69, -70, -71, 152,
|
||||
154, -72, -73, -74, 157, 171, -75, -76, 207, 184, 174, 167, 166,
|
||||
165, -77, -78, -79, 172, 170, -80, -81, -82, 178, -83, 177, 182,
|
||||
-84, -85, 187, 181, -86, -87, -88, -89, 206, 221, -90, 189, -91,
|
||||
198, 254, 262, 195, 196, -92, -93, -94, -95, -96, 252, 255, 250,
|
||||
-97, 211, 209, -98, -99, 212, -100, 213, -101, -102, -103, 224,
|
||||
-104, 232, 227, 220, 226, -105, -106, 246, 236, -107, 243, -108,
|
||||
-109, 231, 237, 235, -110, -111, 239, 238, -112, -113, -114, -115,
|
||||
-116, 241, -117, 244, -118, -119, 248, -120, 249, -121, -122, -123,
|
||||
253, -124, -125, -126, -127, 259, 258, -128, -129, 261, -130, -131,
|
||||
390, 327, 296, 281, 274, 271, 270, -132, -133, 273, -134, -135,
|
||||
278, 277, -136, -137, 280, -138, -139, 289, 286, 285, -140, -141,
|
||||
288, -142, -143, 293, 292, -144, -145, 295, -146, -147, 312, 305,
|
||||
302, 301, -148, -149, 304, -150, -151, 309, 308, -152, -153, 311,
|
||||
-154, -155, 320, 317, 316, -156, -157, 319, -158, -159, 324, 323,
|
||||
-160, -161, 326, -162, -163, 359, 344, 337, 334, 333, -164, -165,
|
||||
336, -166, -167, 341, 340, -168, -169, 343, -170, -171, 352, 349,
|
||||
348, -172, -173, 351, -174, -175, 356, 355, -176, -177, 358, -178,
|
||||
-179, 375, 368, 365, 364, -180, -181, 367, -182, -183, 372, 371,
|
||||
-184, -185, 374, -186, -187, 383, 380, 379, -188, -189, 382, -190,
|
||||
-191, 387, 386, -192, -193, 389, -194, -195, 454, 423, 408, 401,
|
||||
398, 397, -196, -197, 400, -198, -199, 405, 404, -200, -201, 407,
|
||||
-202, -203, 416, 413, 412, -204, -205, 415, -206, -207, 420, 419,
|
||||
-208, -209, 422, -210, -211, 439, 432, 429, 428, -212, -213, 431,
|
||||
-214, -215, 436, 435, -216, -217, 438, -218, -219, 447, 444, 443,
|
||||
-220, -221, 446, -222, -223, 451, 450, -224, -225, 453, -226, -227,
|
||||
486, 471, 464, 461, 460, -228, -229, 463, -230, -231, 468, 467,
|
||||
-232, -233, 470, -234, -235, 479, 476, 475, -236, -237, 478, -238,
|
||||
-239, 483, 482, -240, -241, 485, -242, -243, 499, 495, 492, 491,
|
||||
-244, -245, 494, -246, -247, 497, -248, 502, -249, 506, 503, -250,
|
||||
-251, 505, -252, -253, 508, -254, 510, -255, -256, 0 };
|
||||
|
||||
/**
|
||||
* Constructs a new {@code StringUtils.java} {@code Object}.
|
||||
*/
|
||||
public StringUtils() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
/**
|
||||
* Method used to get the formatted number as a string from the integer inputed.
|
||||
* @param amount the ammount.
|
||||
* @return the string value.
|
||||
*/
|
||||
public static String getFormattedNumber(int amount) {
|
||||
return new DecimalFormat("#,###,##0").format(amount).toString();
|
||||
}
|
||||
/**
|
||||
* Checks if the string contains an invalid character.
|
||||
* @param nameThe string.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean containsInvalidCharacter(String name) {
|
||||
for (char c : name.toCharArray()) {
|
||||
boolean pass = false;
|
||||
for (char vc : VALID_CHARS)
|
||||
if (vc == c) {
|
||||
pass = true;
|
||||
break;
|
||||
}
|
||||
if (!pass)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* If a word starts with a e i o u h for grammar = a + n.
|
||||
* @param word The word.
|
||||
* @return If the a should have +n {@code true}.
|
||||
*/
|
||||
public static boolean isPlusN(String word) {
|
||||
if (word == null)
|
||||
return false;
|
||||
String s = word.toLowerCase();
|
||||
return s.charAt(0) == 'a' || s.charAt(0) == 'e' || s.charAt(0) == 'i'
|
||||
|| s.charAt(0) == 'o' || s.charAt(0) == 'u'
|
||||
|| (s.charAt(0) == 'h' && s.length() > 1 && s.charAt(1) != 'e');
|
||||
}
|
||||
/**
|
||||
* Method used to get the player name as a long.
|
||||
* @param s the string.
|
||||
* @return the long.
|
||||
*/
|
||||
public static long getPlayerNameLong(String s) {
|
||||
long l = 0L;
|
||||
for(int i = 0; i < s.length() && i < 12; i++) {
|
||||
char c = s.charAt(i);
|
||||
l *= 37L;
|
||||
if(c >= 'A' && c <= 'Z') l += (1 + c) - 65;
|
||||
else if(c >= 'a' && c <= 'z') l += (1 + c) - 97;
|
||||
else if(c >= '0' && c <= '9') l += (27 + c) - 48;
|
||||
}
|
||||
while(l % 37L == 0L && l != 0L) l /= 37L;
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to convert the string to a long.
|
||||
* @param s the string.
|
||||
* @return the long.
|
||||
*/
|
||||
public static long convertStringToLong(String s) {
|
||||
if (s.length() > 20) {
|
||||
throw new IllegalArgumentException("String is too long: " + s);
|
||||
}
|
||||
long out = 0L;
|
||||
for (int i = 0; i < s.length(); ++i) {
|
||||
long m = reducedMapping(s.codePointAt(i));
|
||||
if (m == -1) {
|
||||
throw new IllegalArgumentException("Unmapped Character in String: " + s);
|
||||
}
|
||||
m <<= ((9 - i) * 6) + 4;
|
||||
out |= m;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the string as display name.
|
||||
* @param name The string to format.
|
||||
* @return The formatted name.
|
||||
*/
|
||||
public static String formatDisplayName(String name) {
|
||||
name = name.replaceAll("_", " ");
|
||||
name = name.toLowerCase();
|
||||
StringBuilder newName = new StringBuilder();
|
||||
boolean wasSpace = true;
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
if (wasSpace) {
|
||||
newName.append(("" + name.charAt(i)).toUpperCase());
|
||||
wasSpace = false;
|
||||
} else {
|
||||
newName.append(name.charAt(i));
|
||||
}
|
||||
if (name.charAt(i) == ' ') {
|
||||
wasSpace = true;
|
||||
}
|
||||
}
|
||||
return newName.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the byte for the character.
|
||||
* @param c The character.
|
||||
* @return The byte.
|
||||
*/
|
||||
private static final byte getByte(char c) {
|
||||
byte charByte;
|
||||
if (c > 0 && c < '\200' || c >= '\240' && c <= '\377')
|
||||
charByte = (byte) c;
|
||||
else if (c != '\u20AC') {
|
||||
if (c != '\u201A') {
|
||||
if (c != '\u0192') {
|
||||
if (c == '\u201E')
|
||||
charByte = -124;
|
||||
else if (c != '\u2026') {
|
||||
if (c != '\u2020') {
|
||||
if (c == '\u2021')
|
||||
charByte = -121;
|
||||
else if (c == '\u02C6')
|
||||
charByte = -120;
|
||||
else if (c == '\u2030')
|
||||
charByte = -119;
|
||||
else if (c == '\u0160')
|
||||
charByte = -118;
|
||||
else if (c == '\u2039')
|
||||
charByte = -117;
|
||||
else if (c == '\u0152')
|
||||
charByte = -116;
|
||||
else if (c != '\u017D') {
|
||||
if (c == '\u2018')
|
||||
charByte = -111;
|
||||
else if (c != '\u2019') {
|
||||
if (c != '\u201C') {
|
||||
if (c == '\u201D')
|
||||
charByte = -108;
|
||||
else if (c != '\u2022') {
|
||||
if (c == '\u2013')
|
||||
charByte = -106;
|
||||
else if (c == '\u2014')
|
||||
charByte = -105;
|
||||
else if (c == '\u02DC')
|
||||
charByte = -104;
|
||||
else if (c == '\u2122')
|
||||
charByte = -103;
|
||||
else if (c != '\u0161') {
|
||||
if (c == '\u203A')
|
||||
charByte = -101;
|
||||
else if (c != '\u0153') {
|
||||
if (c == '\u017E')
|
||||
charByte = -98;
|
||||
else if (c != '\u0178')
|
||||
charByte = 63;
|
||||
else
|
||||
charByte = -97;
|
||||
} else
|
||||
charByte = -100;
|
||||
} else
|
||||
charByte = -102;
|
||||
} else
|
||||
charByte = -107;
|
||||
} else
|
||||
charByte = -109;
|
||||
} else
|
||||
charByte = -110;
|
||||
} else
|
||||
charByte = -114;
|
||||
} else
|
||||
charByte = -122;
|
||||
} else
|
||||
charByte = -123;
|
||||
} else
|
||||
charByte = -125;
|
||||
} else
|
||||
charByte = -126;
|
||||
} else
|
||||
charByte = -128;
|
||||
return charByte;
|
||||
}
|
||||
/**
|
||||
* Gets the double value of this string
|
||||
* @param s The string.
|
||||
* @return The double value.
|
||||
*/
|
||||
public static double getDouble(String s) {
|
||||
s = s.replaceAll(", ", "").replaceAll(",", "");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
char c;
|
||||
boolean foundStart = false;
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
c = s.charAt(i);
|
||||
if (Character.isDigit(c) || c == '-' || c == '.') {
|
||||
sb.append(c);
|
||||
foundStart = true;
|
||||
} else if (foundStart)
|
||||
break;
|
||||
}
|
||||
try {
|
||||
double amount = Double.parseDouble(sb.toString());
|
||||
return amount;
|
||||
} catch (NumberFormatException e) {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Gets the hash for the string.
|
||||
* @param str The string.
|
||||
* @return The hash.
|
||||
*/
|
||||
public static final int getNameHash(String str) {
|
||||
str = str.toLowerCase();
|
||||
int hash = 0;
|
||||
for (int index = 0; index < str.length(); index++)
|
||||
hash = getByte(str.charAt(index)) + ((hash << 5) - hash);
|
||||
return hash;
|
||||
}
|
||||
/**
|
||||
* Gets the string value of this string (all html/... removed).
|
||||
* @param s The string.
|
||||
* @return The string value.
|
||||
*/
|
||||
public static String getString(String s) {
|
||||
return s.replaceAll("\\<.*?>", "").replaceAll(" ", "")
|
||||
.replaceAll("Discontinued Item:", "");
|
||||
}
|
||||
/**
|
||||
* Characters used to convert a String to a Long.
|
||||
*/
|
||||
public static char[] validChars = {
|
||||
'_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
|
||||
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
|
||||
't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2',
|
||||
'3', '4', '5', '6', '7', '8', '9'
|
||||
};
|
||||
private final static int[] anIntArray233 = {
|
||||
0, 1024, 2048, 3072, 4096, 5120,
|
||||
6144, 8192, 9216, 12288, 10240, 11264, 16384, 18432, 17408, 20480,
|
||||
21504, 22528, 23552, 24576, 25600, 26624, 27648, 28672, 29696,
|
||||
30720, 31744, 32768, 33792, 34816, 35840, 36864, 536870912,
|
||||
16777216, 37888, 65536, 38912, 131072, 196608, 33554432, 524288,
|
||||
1048576, 1572864, 262144, 67108864, 4194304, 134217728, 327680,
|
||||
8388608, 2097152, 12582912, 13631488, 14680064, 15728640,
|
||||
100663296, 101187584, 101711872, 101974016, 102760448, 102236160,
|
||||
40960, 393216, 229376, 117440512, 104857600, 109051904, 201326592,
|
||||
205520896, 209715200, 213909504, 106954752, 218103808, 226492416,
|
||||
234881024, 222298112, 224395264, 268435456, 272629760, 276824064,
|
||||
285212672, 289406976, 223346688, 293601280, 301989888, 318767104,
|
||||
297795584, 298844160, 310378496, 102498304, 335544320, 299892736,
|
||||
300941312, 301006848, 300974080, 39936, 301465600, 49152,
|
||||
1073741824, 369098752, 402653184, 1342177280, 1610612736,
|
||||
469762048, 1476395008, -2147483648, -1879048192, 352321536,
|
||||
1543503872, -2013265920, -1610612736, -1342177280, -1073741824,
|
||||
-1543503872, 356515840, -1476395008, -805306368, -536870912,
|
||||
-268435456, 1577058304, -134217728, 360710144, -67108864,
|
||||
364904448, 51200, 57344, 52224, 301203456, 53248, 54272, 55296,
|
||||
56320, 301072384, 301073408, 301074432, 301075456, 301076480,
|
||||
301077504, 301078528, 301079552, 301080576, 301081600, 301082624,
|
||||
301083648, 301084672, 301085696, 301086720, 301087744, 301088768,
|
||||
301089792, 301090816, 301091840, 301092864, 301093888, 301094912,
|
||||
301095936, 301096960, 301097984, 301099008, 301100032, 301101056,
|
||||
301102080, 301103104, 301104128, 301105152, 301106176, 301107200,
|
||||
301108224, 301109248, 301110272, 301111296, 301112320, 301113344,
|
||||
301114368, 301115392, 301116416, 301117440, 301118464, 301119488,
|
||||
301120512, 301121536, 301122560, 301123584, 301124608, 301125632,
|
||||
301126656, 301127680, 301128704, 301129728, 301130752, 301131776,
|
||||
301132800, 301133824, 301134848, 301135872, 301136896, 301137920,
|
||||
301138944, 301139968, 301140992, 301142016, 301143040, 301144064,
|
||||
301145088, 301146112, 301147136, 301148160, 301149184, 301150208,
|
||||
301151232, 301152256, 301153280, 301154304, 301155328, 301156352,
|
||||
301157376, 301158400, 301159424, 301160448, 301161472, 301162496,
|
||||
301163520, 301164544, 301165568, 301166592, 301167616, 301168640,
|
||||
301169664, 301170688, 301171712, 301172736, 301173760, 301174784,
|
||||
301175808, 301176832, 301177856, 301178880, 301179904, 301180928,
|
||||
301181952, 301182976, 301184000, 301185024, 301186048, 301187072,
|
||||
301188096, 301189120, 301190144, 301191168, 301193216, 301195264,
|
||||
301194240, 301197312, 301198336, 301199360, 301201408, 301202432
|
||||
};
|
||||
private final static byte[] aByteArray235 = {
|
||||
22, 22, 22, 22, 22, 22, 21, 22, 22,
|
||||
20, 22, 22, 22, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 3, 8, 22, 16, 22, 16, 17, 7, 13, 13, 13,
|
||||
16, 7, 10, 6, 16, 10, 11, 12, 12, 12, 12, 13, 13, 14, 14, 11, 14,
|
||||
19, 15, 17, 8, 11, 9, 10, 10, 10, 10, 11, 10, 9, 7, 12, 11, 10, 10,
|
||||
9, 10, 10, 12, 10, 9, 8, 12, 12, 9, 14, 8, 12, 17, 16, 17, 22, 13,
|
||||
21, 4, 7, 6, 5, 3, 6, 6, 5, 4, 10, 7, 5, 6, 4, 4, 6, 10, 5, 4, 4,
|
||||
5, 7, 6, 10, 6, 10, 22, 19, 22, 14, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 21, 22, 21, 22, 22, 22, 21,
|
||||
22, 22
|
||||
};
|
||||
/**
|
||||
* Encrypt a string for the client.
|
||||
*/
|
||||
public static int encryptPlayerChat(byte[] is, int i_25_, int i_26_, int i_27_, byte[] is_28_) {
|
||||
try {
|
||||
i_27_ += i_25_;
|
||||
int i_29_ = 0;
|
||||
int i_30_ = i_26_ << 3;
|
||||
for (; i_27_ > i_25_; i_25_++) {
|
||||
int i_31_ = 0xff & is_28_[i_25_];
|
||||
int i_32_ = anIntArray233[i_31_];
|
||||
int i_33_ = aByteArray235[i_31_];
|
||||
int i_34_ = i_30_ >> 3;
|
||||
int i_35_ = i_30_ & 0x7;
|
||||
i_29_ &= (-i_35_ >> 31);
|
||||
i_30_ += i_33_;
|
||||
int i_36_ = ((-1 + (i_35_ - -i_33_)) >> 3) + i_34_;
|
||||
i_35_ += 24;
|
||||
is[i_34_] = (byte) (i_29_ = (i_29_ | (i_32_ >>> i_35_)));
|
||||
if ((i_36_ ^ 0xffffffff) < (i_34_ ^ 0xffffffff)) {
|
||||
i_34_++;
|
||||
i_35_ -= 8;
|
||||
is[i_34_] = (byte) (i_29_ = i_32_ >>> i_35_);
|
||||
if (i_36_ > i_34_) {
|
||||
i_34_++;
|
||||
i_35_ -= 8;
|
||||
is[i_34_] = (byte) (i_29_ = i_32_ >>> i_35_);
|
||||
if (i_36_ > i_34_) {
|
||||
i_35_ -= 8;
|
||||
i_34_++;
|
||||
is[i_34_] = (byte) (i_29_ = i_32_ >>> i_35_);
|
||||
if (i_34_ < i_36_) {
|
||||
i_35_ -= 8;
|
||||
i_34_++;
|
||||
is[i_34_] = (byte) (i_29_ = i_32_ << -i_35_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -i_26_ + ((7 + i_30_) >> 3);
|
||||
} catch (RuntimeException runtimeexception) {
|
||||
runtimeexception.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Gets an integer value from a string.
|
||||
* @param s the string.
|
||||
* @return The value;
|
||||
*/
|
||||
public static int getValue(String s) {
|
||||
s = s.replaceAll(", ", "").replaceAll(",", "");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
char c;
|
||||
boolean foundStart = false;
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
c = s.charAt(i);
|
||||
if (Character.isDigit(c) || c == '-') {
|
||||
sb.append(c);
|
||||
foundStart = true;
|
||||
} else if (foundStart)
|
||||
break;
|
||||
}
|
||||
try {
|
||||
int amount = Integer.parseInt(sb.toString());
|
||||
return amount;
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks if the account name is valid.
|
||||
* @param name The account name.
|
||||
* @return {@code True} if the account name is invalid.
|
||||
*/
|
||||
public static boolean invalidAccountName(String name) {
|
||||
return name.length() < 2 || name.length() > 12 || name.startsWith("_")|| name.endsWith("_") || name.contains("__") || containsInvalidCharacter(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a long to a string.
|
||||
* @param l The long.
|
||||
* @return The string.
|
||||
*/
|
||||
public static String longToString(long l) {
|
||||
int i = 0;
|
||||
char ac[] = new char[32];
|
||||
while (l != 0L) {
|
||||
long l1 = l;
|
||||
l /= 37L;
|
||||
ac[11 - i++] = VALID_CHARS[(int) (l1 - l * 37L)];
|
||||
}
|
||||
return new String(ac, 12 - i, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs a GJ2-String.
|
||||
* @param position The position to start.
|
||||
* @param buffer The byte-array.
|
||||
* @param str The string.
|
||||
* @return The size of the string.
|
||||
*/
|
||||
public static final int packGJString2(int position, byte[] buffer,
|
||||
String str) {
|
||||
int length = str.length();
|
||||
int offset = position;
|
||||
for (int index = 0; length > index; index++) {
|
||||
int character = str.charAt(index);
|
||||
if (character > 127) {
|
||||
if (character > 2047) {
|
||||
buffer[offset++] = (byte) ((character | 919275) >> 12);
|
||||
buffer[offset++] = (byte) (128 | ((character >> 6) & 63));
|
||||
buffer[offset++] = (byte) (128 | (character & 63));
|
||||
} else {
|
||||
buffer[offset++] = (byte) ((character | 12309) >> 6);
|
||||
buffer[offset++] = (byte) (128 | (character & 63));
|
||||
}
|
||||
} else
|
||||
buffer[offset++] = (byte) character;
|
||||
}
|
||||
return offset - position;
|
||||
}
|
||||
/**
|
||||
* Method used to...
|
||||
* @param x idk,
|
||||
* @return the idk.
|
||||
*/
|
||||
public static long reducedMapping(int x) {
|
||||
long out = -1;
|
||||
if (x >= 97 && x <= 122)
|
||||
out = x - 96;
|
||||
else if (x >= 65 && x <= 90)
|
||||
out = x - 37;
|
||||
else if (x >= 48 && x <= 57)
|
||||
out = x - +5;
|
||||
else if (x == 32)
|
||||
out = 63L;
|
||||
return out;
|
||||
}
|
||||
/**
|
||||
* Converts a string to a long.
|
||||
* @param s The string.
|
||||
* @return The long.
|
||||
*/
|
||||
public static long stringToLong(String s) {
|
||||
long l = 0L;
|
||||
for (int i = 0; i < s.length() && i < 12; i++) {
|
||||
char c = s.charAt(i);
|
||||
l *= 37L;
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
l += (1 + c) - 65;
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
l += (1 + c) - 97;
|
||||
else if (c >= '0' && c <= '9')
|
||||
l += (27 + c) - 48;
|
||||
}
|
||||
while (l % 37L == 0L && l != 0L)
|
||||
l /= 37L;
|
||||
return l;
|
||||
}
|
||||
/**
|
||||
* Decrypt player chat.
|
||||
*
|
||||
* @param buffer
|
||||
* The buffer
|
||||
* @param totalChars
|
||||
* The total chars
|
||||
* @return The string
|
||||
*/
|
||||
public static String decryptPlayerChat(IoBuffer buffer, int totalChars) {
|
||||
try {
|
||||
if (totalChars == 0)
|
||||
return "";
|
||||
int charsDecoded = 0;
|
||||
int i_4_ = 0;
|
||||
String s = "";
|
||||
for (;;) {
|
||||
byte i_7_ = (byte) buffer.get();
|
||||
if (i_7_ >= 0)
|
||||
i_4_++;
|
||||
else
|
||||
i_4_ = anIntArray241[i_4_];
|
||||
int i_8_;
|
||||
if ((i_8_ = anIntArray241[i_4_]) < 0) {
|
||||
s += (char) (byte) (i_8_ ^ 0xffffffff);
|
||||
if (totalChars <= ++charsDecoded)
|
||||
break;
|
||||
i_4_ = 0;
|
||||
}
|
||||
if (((i_7_ & 0x40) ^ 0xffffffff) != -1)
|
||||
i_4_ = anIntArray241[i_4_];
|
||||
else
|
||||
i_4_++;
|
||||
if ((i_8_ = anIntArray241[i_4_]) < 0) {
|
||||
s += (char) (byte) (i_8_ ^ 0xffffffff);
|
||||
if (++charsDecoded >= totalChars)
|
||||
break;
|
||||
i_4_ = 0;
|
||||
}
|
||||
if ((0x20 & i_7_) == 0)
|
||||
i_4_++;
|
||||
else
|
||||
i_4_ = anIntArray241[i_4_];
|
||||
if ((i_8_ = anIntArray241[i_4_]) < 0) {
|
||||
s += (char) (byte) (i_8_ ^ 0xffffffff);
|
||||
if (totalChars <= ++charsDecoded)
|
||||
break;
|
||||
i_4_ = 0;
|
||||
}
|
||||
if (((0x10 & i_7_) ^ 0xffffffff) == -1)
|
||||
i_4_++;
|
||||
else
|
||||
i_4_ = anIntArray241[i_4_];
|
||||
if ((i_8_ = anIntArray241[i_4_]) < 0) {
|
||||
s += (char) (byte) (i_8_ ^ 0xffffffff);
|
||||
if (totalChars <= ++charsDecoded)
|
||||
break;
|
||||
|
||||
i_4_ = 0;
|
||||
}
|
||||
if (((0x8 & i_7_) ^ 0xffffffff) != -1)
|
||||
i_4_ = anIntArray241[i_4_];
|
||||
else
|
||||
i_4_++;
|
||||
if ((i_8_ = anIntArray241[i_4_]) < 0) {
|
||||
s += (char) (byte) (i_8_ ^ 0xffffffff);
|
||||
if (++charsDecoded >= totalChars)
|
||||
break;
|
||||
i_4_ = 0;
|
||||
}
|
||||
if ((0x4 & i_7_) == 0)
|
||||
i_4_++;
|
||||
else
|
||||
i_4_ = anIntArray241[i_4_];
|
||||
if ((i_8_ = anIntArray241[i_4_]) < 0) {
|
||||
s += (char) (byte) (i_8_ ^ 0xffffffff);
|
||||
if (totalChars <= ++charsDecoded)
|
||||
break;
|
||||
i_4_ = 0;
|
||||
}
|
||||
if (((i_7_ & 0x2) ^ 0xffffffff) != -1)
|
||||
i_4_ = anIntArray241[i_4_];
|
||||
else
|
||||
i_4_++;
|
||||
if ((i_8_ = anIntArray241[i_4_]) < 0) {
|
||||
s += (char) (byte) (i_8_ ^ 0xffffffff);
|
||||
if (totalChars <= ++charsDecoded)
|
||||
break;
|
||||
i_4_ = 0;
|
||||
}
|
||||
if (((i_7_ & 0x1) ^ 0xffffffff) != -1)
|
||||
i_4_ = anIntArray241[i_4_];
|
||||
else
|
||||
i_4_++;
|
||||
if ((i_8_ = anIntArray241[i_4_]) < 0) {
|
||||
s += (char) (byte) (i_8_ ^ 0xffffffff);
|
||||
if (++charsDecoded >= totalChars)
|
||||
break;
|
||||
i_4_ = 0;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
} catch (RuntimeException runtimeexception) {
|
||||
runtimeexception.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package ms.system.util;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* A class holding methods to execute tasks.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class TaskExecutor {
|
||||
|
||||
/**
|
||||
* The executor to use.
|
||||
*/
|
||||
private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
/**
|
||||
* The SQL task executor.
|
||||
*/
|
||||
private static final ScheduledExecutorService SQL_EXECUTOR = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TaskExecutor} {@code Object}.
|
||||
*/
|
||||
private TaskExecutor() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL handling task.
|
||||
* @param task The task.
|
||||
*/
|
||||
public static void executeSQL(Runnable task) {
|
||||
SQL_EXECUTOR.execute(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the task.
|
||||
* @param task The task to execute.
|
||||
*/
|
||||
public static void execute(Runnable task) {
|
||||
EXECUTOR.execute(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the executor.
|
||||
* @return The executor.
|
||||
*/
|
||||
public static ScheduledExecutorService getExecutor() {
|
||||
return EXECUTOR;
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
package ms.world;
|
||||
|
||||
import ms.net.IoSession;
|
||||
import ms.net.packet.WorldPacketRepository;
|
||||
import ms.system.mysql.SQLEntryHandler;
|
||||
import ms.system.mysql.WorldListSQLHandler;
|
||||
import ms.system.util.TaskExecutor;
|
||||
import ms.world.info.Response;
|
||||
import ms.world.info.WorldInfo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Represents a game world.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class GameServer {
|
||||
|
||||
/**
|
||||
* The world info.
|
||||
*/
|
||||
private final WorldInfo info;
|
||||
|
||||
/**
|
||||
* The I/O session.
|
||||
*/
|
||||
private IoSession session;
|
||||
|
||||
/**
|
||||
* The players active on the game server.
|
||||
*/
|
||||
private final Map<String, PlayerSession> players = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The scheduled future for the updating task.
|
||||
*/
|
||||
private ScheduledFuture<?> future;
|
||||
|
||||
/**
|
||||
* constructs a new {@code GameServer} {@code Object}.
|
||||
* @param info The world info.
|
||||
*/
|
||||
public GameServer(WorldInfo info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the game server.
|
||||
* @param session The I/O session.
|
||||
*/
|
||||
public void configure(IoSession session) {
|
||||
this.session = session;
|
||||
session.setGameServer(this);
|
||||
future = TaskExecutor.getExecutor().scheduleAtFixedRate(() -> {
|
||||
SQLEntryHandler.write(new WorldListSQLHandler(GameServer.this));
|
||||
if (!isActive()) {
|
||||
future.cancel(false);
|
||||
future = null;
|
||||
}
|
||||
}, 0, 10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a player.
|
||||
* @param player The player.
|
||||
*/
|
||||
public void register(PlayerSession player) {
|
||||
players.put(player.getUsername(), player);
|
||||
player.setWorld(this);
|
||||
player.setActive(true);
|
||||
player.setWorldId(info.getWorldId());
|
||||
player.configure();
|
||||
WorldPacketRepository.sendRegistryResponse(this, player, Response.SUCCESSFUL);
|
||||
player.getCommunication().sync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the game server is active.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return session.isActive();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the playerAmount
|
||||
*/
|
||||
public int getPlayerAmount() {
|
||||
return players.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the info
|
||||
*/
|
||||
public WorldInfo getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the session
|
||||
*/
|
||||
public IoSession getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param session the session to set
|
||||
*/
|
||||
public void setSession(IoSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the players value.
|
||||
* @return The players.
|
||||
*/
|
||||
public Map<String, PlayerSession> getPlayers() {
|
||||
return players;
|
||||
}
|
||||
}
|
||||
@@ -1,475 +0,0 @@
|
||||
package ms.world;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import ms.ServerConstants;
|
||||
import ms.system.communication.ClanRepository;
|
||||
import ms.system.communication.CommunicationInfo;
|
||||
import ms.system.mysql.SQLManager;
|
||||
import ms.world.info.UIDInfo;
|
||||
|
||||
/**
|
||||
* Represents a player session.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class PlayerSession {
|
||||
|
||||
/**
|
||||
* The player's communication info.
|
||||
*/
|
||||
private CommunicationInfo communication = new CommunicationInfo(this);
|
||||
|
||||
/**
|
||||
* The game server the player is currently in.
|
||||
*/
|
||||
private GameServer world;
|
||||
|
||||
/**
|
||||
* The current clan.
|
||||
*/
|
||||
private ClanRepository clan;
|
||||
|
||||
/**
|
||||
* The player's UID info.
|
||||
*/
|
||||
private UIDInfo uid;
|
||||
|
||||
/**
|
||||
* The username.
|
||||
*/
|
||||
private final String username;
|
||||
|
||||
/**
|
||||
* The password.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* The player's rights.
|
||||
*/
|
||||
private int rights;
|
||||
|
||||
/**
|
||||
* The world id.
|
||||
*/
|
||||
private int worldId;
|
||||
|
||||
/**
|
||||
* If the player session is active.
|
||||
*/
|
||||
private boolean active;
|
||||
|
||||
/**
|
||||
* The time stamp of last disconnection.
|
||||
*/
|
||||
private long disconnectionTime = 0L;
|
||||
|
||||
/**
|
||||
* How long the player is banned for.
|
||||
*/
|
||||
private long banTime;
|
||||
|
||||
/**
|
||||
* How long the player is muted for.
|
||||
*/
|
||||
private long muteTime;
|
||||
|
||||
/**
|
||||
* The last world the player logged in.
|
||||
*/
|
||||
private int lastWorld = -1;
|
||||
|
||||
/**
|
||||
* The chat icon.
|
||||
*/
|
||||
private int chatIcon;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PlayerSession} {@code Object}.
|
||||
* @param username The username.
|
||||
* @param password The password.
|
||||
* @param ipAddress The ip address.
|
||||
* @param macAddress The mac address.
|
||||
* @param computerName The computer name.
|
||||
* @param serial The motherboard serial key.
|
||||
*/
|
||||
public PlayerSession(String username, String password, UIDInfo uid) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the session's data from the database.
|
||||
* @return {@code True} if parsed.
|
||||
*/
|
||||
public boolean parse() {
|
||||
Connection connection = SQLManager.getConnection();
|
||||
if (connection == null) {
|
||||
return false;
|
||||
}
|
||||
ResultSet result = null;
|
||||
PreparedStatement statement;
|
||||
try {
|
||||
statement = connection.prepareStatement("SELECT * FROM " + "members" + " WHERE " + "" + "username" + "='" + username.toLowerCase() + "' LIMIT 1");
|
||||
result = statement.executeQuery();
|
||||
if (result == null || !result.next()) {
|
||||
SQLManager.close(connection);
|
||||
return false;
|
||||
}
|
||||
rights = result.getInt("rights");
|
||||
disconnectionTime = result.getLong("disconnectTime");
|
||||
lastWorld = result.getInt("lastWorld");
|
||||
banTime = result.getLong("banTime");
|
||||
communication.parse(result);
|
||||
uid.parse(result);
|
||||
SQLManager.close(connection);
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
SQLManager.close(connection);
|
||||
return false;
|
||||
} finally {
|
||||
SQLManager.close(connection);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a session is removed.
|
||||
*/
|
||||
public void remove() {
|
||||
if (world != null && world.getInfo().getRevision() == 498) {
|
||||
return;
|
||||
}
|
||||
Connection connection = SQLManager.getConnection();
|
||||
if (connection == null) {
|
||||
return;
|
||||
}
|
||||
PreparedStatement statement;
|
||||
try {
|
||||
statement = connection.prepareStatement("UPDATE members SET disconnectTime = ?, lastWorld = ?, contacts = ?, blocked = ?, clanName = ?, currentClan = ?, clanReqs = ?, chatSettings = ?, online= ? WHERE username = ?");
|
||||
statement.setLong(1, System.currentTimeMillis());
|
||||
statement.setInt(2, worldId);
|
||||
communication.save(statement);
|
||||
statement.setBoolean(9, false);
|
||||
statement.setString(10, username);
|
||||
statement.executeUpdate();
|
||||
SQLManager.close(connection);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
SQLManager.close(connection);
|
||||
} finally {
|
||||
SQLManager.close(connection);
|
||||
}
|
||||
communication.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a player session.
|
||||
* @param username the username.
|
||||
* @return the player session.
|
||||
*/
|
||||
public static PlayerSession get(String username) {
|
||||
PlayerSession session = new PlayerSession(username, "", new UIDInfo());
|
||||
if (!session.parse()) {
|
||||
return null;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the player session.
|
||||
*/
|
||||
public void configure() {
|
||||
ClanRepository clan = ClanRepository.getClans().get(username);
|
||||
if (clan != null) {
|
||||
clan.setOwner(this);
|
||||
}
|
||||
Connection connection = SQLManager.getConnection();
|
||||
if (connection == null) {
|
||||
return;
|
||||
}
|
||||
PreparedStatement statement;
|
||||
try {
|
||||
statement = connection.prepareStatement("UPDATE members SET online = ?, lastWorld = ?, lastLogin = ? WHERE username = ?");
|
||||
statement.setBoolean(1, true);
|
||||
statement.setInt(2, worldId);
|
||||
statement.setLong(3, System.currentTimeMillis());
|
||||
statement.setString(4, username);
|
||||
statement.execute();
|
||||
SQLManager.close(connection);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
SQLManager.close(connection);
|
||||
} finally {
|
||||
SQLManager.close(connection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has just moved worlds.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasMovedWorld() {
|
||||
if (rights == 2) {
|
||||
return false;
|
||||
}
|
||||
return System.currentTimeMillis() - disconnectionTime < ServerConstants.WORLD_SWITCH_DELAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the username value.
|
||||
* @return The username.
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the password value.
|
||||
* @return The password.
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chat icon.
|
||||
* @return The chat icon.
|
||||
*/
|
||||
public int getChatIcon() {
|
||||
return chatIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ipAddress value.
|
||||
* @return The ipAddress.
|
||||
*/
|
||||
public String getIpAddress() {
|
||||
return uid.getIp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the macAddress value.
|
||||
* @return The macAddress.
|
||||
*/
|
||||
public String getMacAddress() {
|
||||
return uid.getMac();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the computerName value.
|
||||
* @return The computerName.
|
||||
*/
|
||||
public String getComputerName() {
|
||||
return uid.getCompName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the worldId value.
|
||||
* @return The worldId.
|
||||
*/
|
||||
public int getWorldId() {
|
||||
return worldId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the worldId value.
|
||||
* @param worldId The worldId to set.
|
||||
*/
|
||||
public void setWorldId(int worldId) {
|
||||
this.worldId = worldId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the active value.
|
||||
* @return The active.
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active value.
|
||||
* @param active The active to set.
|
||||
*/
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the serialKey value.
|
||||
* @return The serialKey.
|
||||
*/
|
||||
public String getSerialKey() {
|
||||
return uid.getSerial();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rights value.
|
||||
* @return The rights.
|
||||
*/
|
||||
public int getRights() {
|
||||
return rights;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rights value.
|
||||
* @param rights The rights to set.
|
||||
*/
|
||||
public void setRights(int rights) {
|
||||
this.rights = rights;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the player is banned.
|
||||
* @return {@code true} if so.
|
||||
*/
|
||||
public boolean isBanned() {
|
||||
return banTime > System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the banTime value.
|
||||
* @return The banTime.
|
||||
*/
|
||||
public long getBanTime() {
|
||||
return banTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the muteTime.
|
||||
* @return the muteTime.
|
||||
*/
|
||||
public long getMuteTime() {
|
||||
return muteTime;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the muteTime.
|
||||
* @param muteTime the muteTime to set
|
||||
*/
|
||||
public void setMuteTime(long muteTime) {
|
||||
this.muteTime = muteTime;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the disconnectionTime value.
|
||||
* @return The disconnectionTime.
|
||||
*/
|
||||
public long getDisconnectionTime() {
|
||||
return disconnectionTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lastWorld value.
|
||||
* @return The lastWorld.
|
||||
*/
|
||||
public int getLastWorld() {
|
||||
return lastWorld;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lastWorld value.
|
||||
* @param lastWorld The lastWorld to set.
|
||||
*/
|
||||
public void setLastWorld(int lastWorld) {
|
||||
this.lastWorld = lastWorld;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the communication value.
|
||||
* @return The communication.
|
||||
*/
|
||||
public CommunicationInfo getCommunication() {
|
||||
return communication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the communication value.
|
||||
* @param communication The communication to set.
|
||||
*/
|
||||
public void setCommunication(CommunicationInfo communication) {
|
||||
this.communication = communication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world value.
|
||||
* @return The world.
|
||||
*/
|
||||
public GameServer getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the world value.
|
||||
* @param world The world to set.
|
||||
*/
|
||||
public void setWorld(GameServer world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clan value.
|
||||
* @return The clan.
|
||||
*/
|
||||
public ClanRepository getClan() {
|
||||
return clan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the clan value.
|
||||
* @param clan The clan to set.
|
||||
*/
|
||||
public void setClan(ClanRepository clan) {
|
||||
this.clan = clan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the chat icon.
|
||||
* @param chatIcon
|
||||
*/
|
||||
public void setChatIcon(int chatIcon) {
|
||||
this.chatIcon = chatIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the uid.
|
||||
* @return the uid.
|
||||
*/
|
||||
public UIDInfo getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the uid.
|
||||
* @param uid the uid to set
|
||||
*/
|
||||
public void setUid(UIDInfo uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the disconnect time.
|
||||
* @param time the time.
|
||||
*/
|
||||
public void setDisconnectTime(long time) {
|
||||
this.disconnectionTime = time;
|
||||
}
|
||||
|
||||
public boolean equalsSession(PlayerSession o){
|
||||
return username.equals(o.username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "player [name=" + username + ", pass=" + password + ", ip=" + uid.getIp() + ", mac=" + uid.getMac() + ", comp=" + uid.getCompName() + ", msk=" + uid.getSerial() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,275 +0,0 @@
|
||||
package ms.world;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import ms.ServerConstants;
|
||||
import ms.net.IoSession;
|
||||
import ms.net.packet.IoBuffer;
|
||||
import ms.world.info.CountryFlag;
|
||||
import ms.world.info.WorldInfo;
|
||||
import ms09.MSLogger;
|
||||
|
||||
/**
|
||||
* Holds all the world servers.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public class WorldDatabase {
|
||||
|
||||
/**
|
||||
* The game servers.
|
||||
*/
|
||||
private static final GameServer[] DATABASE = new GameServer[ServerConstants.WORLD_LIMIT];
|
||||
|
||||
/**
|
||||
* The update time stamp.
|
||||
*/
|
||||
private static long updateStamp = System.currentTimeMillis();
|
||||
|
||||
/**
|
||||
* Used to prevent {@code WorldDatabase} from getting instantiated.
|
||||
*/
|
||||
private WorldDatabase() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the packet to update the world list in the lobby.
|
||||
* @param player The player.
|
||||
* @param worldConfiguration If the configuration should be added.
|
||||
* @param worldStatus If the status should be added.
|
||||
* @return The {@code OutgoingPacket} to write.
|
||||
*/
|
||||
public static void sendUpdate(IoSession session, int updateStamp) {
|
||||
ByteBuffer buf = ByteBuffer.allocate(1024);
|
||||
buf.put((byte) 0);
|
||||
buf.putShort((short) 0);
|
||||
buf.put((byte) 1);
|
||||
IoBuffer buffer = new IoBuffer();
|
||||
if (updateStamp == (int) WorldDatabase.updateStamp) {
|
||||
buf.put((byte) 0);
|
||||
} else {
|
||||
buf.put((byte) 1); // Indicates an update occured.
|
||||
putWorldListinfo(buffer);
|
||||
}
|
||||
putPlayerInfo(buffer);
|
||||
if (buffer.toByteBuffer().position() > 0) {
|
||||
buf.put((ByteBuffer) buffer.toByteBuffer().flip());
|
||||
}
|
||||
buf.putShort(1, (short) (buf.position() - 3));
|
||||
session.queue((ByteBuffer) buf.flip());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the world status on the packet.
|
||||
* @param buffer The current packet.
|
||||
*/
|
||||
private static void putPlayerInfo(IoBuffer buffer) {
|
||||
for (GameServer server : DATABASE) {
|
||||
if (server != null) {
|
||||
WorldInfo w = server.getInfo();
|
||||
buffer.putSmart(w.getWorldId());
|
||||
buffer.putShort(server.isActive() ? server.getPlayerAmount() : -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the countries for each world.
|
||||
* @param buffer The current packet.
|
||||
*/
|
||||
private static void putCountryInfo(IoBuffer buffer) {
|
||||
for (CountryFlag country : CountryFlag.values()) {
|
||||
buffer.putSmart(country.getId());
|
||||
buffer.putJagString(capitalize(country.name().toLowerCase()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to a capitalized string
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
private static String capitalize(String name) {
|
||||
if (name == null || name.length() == 0) {
|
||||
return name;
|
||||
} else {
|
||||
char[] chars = name.toCharArray();
|
||||
chars[0] = Character.toUpperCase(chars[0]);
|
||||
return new String(chars);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the world configuration on the packet.
|
||||
* @param buffer The current packet.
|
||||
*/
|
||||
private static void putWorldListinfo(IoBuffer buffer) {
|
||||
buffer.putSmart(CountryFlag.values().length);
|
||||
putCountryInfo(buffer);
|
||||
buffer.putSmart(0);
|
||||
buffer.putSmart(DATABASE.length);
|
||||
buffer.putSmart(getRegisteredAmount());
|
||||
for (GameServer server : DATABASE) {
|
||||
if (server != null) {
|
||||
WorldInfo w = server.getInfo();
|
||||
buffer.putSmart(w.getWorldId());
|
||||
buffer.put(w.getCountry().ordinal());
|
||||
buffer.putInt(w.getSettings());
|
||||
buffer.putJagString(w.getActivity());
|
||||
buffer.putJagString(w.getAddress());
|
||||
}
|
||||
}
|
||||
buffer.putInt((int) updateStamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of worlds registered.
|
||||
* @return The amount of worlds registered.
|
||||
*/
|
||||
public static int getRegisteredAmount() {
|
||||
int count = 0;
|
||||
for (GameServer server : DATABASE) {
|
||||
if (server != null) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a game server.
|
||||
* @param info The game world info.
|
||||
*/
|
||||
public static GameServer register(WorldInfo info) {
|
||||
GameServer server = DATABASE[info.getWorldId()];
|
||||
if (server != null && server.getSession().isActive() && !server.getSession().getAddress().equals(info.getAddress())) {
|
||||
throw new IllegalStateException("World " + info.getWorldId() + " is already registered!");
|
||||
}
|
||||
flagUpdate();
|
||||
MSLogger.logInfo("Registered world - [id=" + info.getWorldId() + ", ip=" + info.getAddress() + ", country=" + info.getCountry().name().toLowerCase() + ", revision=" + info.getRevision() + "]!");
|
||||
return DATABASE[info.getWorldId()] = new GameServer(info);
|
||||
}
|
||||
|
||||
public static void unRegister(GameServer server){
|
||||
int index = -1;
|
||||
for(int i = 0; i < DATABASE.length; i++){
|
||||
GameServer s = DATABASE[i];
|
||||
if(s == server){
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(index != -1){
|
||||
DATABASE[index] = null;
|
||||
WorldInfo info = server.getInfo();
|
||||
MSLogger.logInfo("Unregistered world - [id=" + info.getWorldId() + ", ip=" + info.getAddress() + ", country=" + info.getCountry().name().toLowerCase() + ", revision=" + info.getRevision() + "]!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world id of the player.
|
||||
* @param username The username of the player.
|
||||
* @return The world id.
|
||||
*/
|
||||
public static int getWorldId(String username) {
|
||||
return getWorldId(getPlayer(username));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world id of the player.
|
||||
* @param player The player.
|
||||
* @return The world id.
|
||||
*/
|
||||
public static int getWorldId(PlayerSession player) {
|
||||
if (player == null || !player.isActive()) {
|
||||
return 0;
|
||||
}
|
||||
return player.getWorldId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the game world is active.
|
||||
* @param worldId The world id.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean isActive(int worldId) {
|
||||
GameServer server = get(worldId);
|
||||
return server != null && server.isActive();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player session for the given name is active.
|
||||
* @param username The player's username.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean isActivePlayer(String username) {
|
||||
PlayerSession session = getPlayer(username);
|
||||
return session != null && session.isActive();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player session for the given name.
|
||||
* @param username The player's username.
|
||||
* @return The player session.
|
||||
*/
|
||||
public static PlayerSession getPlayer(String username) {
|
||||
return getPlayer(username, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player session for the given name.
|
||||
* @param username The player's username.
|
||||
* @param load If we load the users data.
|
||||
* @return The player session.
|
||||
*/
|
||||
public static PlayerSession getPlayer(String username, boolean load) {
|
||||
for (GameServer server : DATABASE) {
|
||||
if (server != null && server.isActive()) {
|
||||
PlayerSession player = server.getPlayers().get(username);
|
||||
if (player != null) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (load) {
|
||||
return PlayerSession.get(username);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the game server for the given world id.
|
||||
* @param worldId The world id.
|
||||
* @return The game server.
|
||||
*/
|
||||
public static GameServer get(int worldId) {
|
||||
return DATABASE[worldId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the game servers.
|
||||
* @return The list of game servers.
|
||||
*/
|
||||
public static GameServer[] getWorlds() {
|
||||
return DATABASE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the updateStamp.
|
||||
* @return the updateStamp
|
||||
*/
|
||||
public static long getUpdateStamp() {
|
||||
return updateStamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the updateStamp.
|
||||
* @param updateStamp the updateStamp to set.
|
||||
*/
|
||||
public static void flagUpdate() {
|
||||
WorldDatabase.updateStamp = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package ms.world.info;
|
||||
|
||||
/**
|
||||
* The country flags.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public enum CountryFlag {
|
||||
|
||||
/**
|
||||
* Belgium
|
||||
*/
|
||||
BELGIUM(22),
|
||||
|
||||
/**
|
||||
* Canada.
|
||||
*/
|
||||
CANADA(38),
|
||||
|
||||
/**
|
||||
* The united kingdom.
|
||||
*/
|
||||
UNITED_KINGDOM(77),
|
||||
|
||||
/**
|
||||
* Netherlands
|
||||
*/
|
||||
NETHERLANDS(161),
|
||||
|
||||
/**
|
||||
* Sweden
|
||||
*/
|
||||
SWEDEN(191),
|
||||
|
||||
/**
|
||||
* Finland
|
||||
*/
|
||||
FINLAND(69),
|
||||
|
||||
/**
|
||||
* Australia.
|
||||
*/
|
||||
AUSTRALIA(16),
|
||||
|
||||
/**
|
||||
* America (USA)
|
||||
*/
|
||||
UNITED_STATES_OF_AMERICA(225),
|
||||
|
||||
/**
|
||||
* Norway
|
||||
*/
|
||||
NORWAY(162),
|
||||
|
||||
/**
|
||||
* Ireland
|
||||
*/
|
||||
IRELAND(101),
|
||||
|
||||
/**
|
||||
* DENMARK
|
||||
*/
|
||||
DENMARK(58),
|
||||
|
||||
/**
|
||||
* Brazil
|
||||
*/
|
||||
BRAZIL(31),
|
||||
|
||||
/**
|
||||
* Mexico
|
||||
*/
|
||||
MEXICO(152),
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* The flag id.
|
||||
*/
|
||||
private final int id;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CountryFlag} {@code Object}.
|
||||
* @param id The flag id.
|
||||
*/
|
||||
private CountryFlag(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
package ms.world.info;
|
||||
|
||||
/**
|
||||
* Holds the response codes during the attempt to login.
|
||||
* @author Emperor
|
||||
*/
|
||||
public enum Response {
|
||||
|
||||
/**
|
||||
* An unexpected server response occurred.
|
||||
*/
|
||||
UNEXPECTED_RESPONSE(0),
|
||||
|
||||
/**
|
||||
* Could not display advertisement video, logging in in x seconds.
|
||||
*/
|
||||
COULD_NOT_DISPLAY_AD(1),
|
||||
|
||||
/**
|
||||
* A successful login.
|
||||
*/
|
||||
SUCCESSFUL(2),
|
||||
|
||||
/**
|
||||
* Invalid username or password has been entered.
|
||||
*/
|
||||
INVALID_CREDENTIALS(3),
|
||||
|
||||
/**
|
||||
* This account is banned.
|
||||
*/
|
||||
ACCOUNT_DISABLED(4),
|
||||
|
||||
/**
|
||||
* This account is already logged in.
|
||||
*/
|
||||
ALREADY_ONLINE(5),
|
||||
|
||||
/**
|
||||
* We have updated and client needs to be reloaded.
|
||||
*/
|
||||
UPDATED(6),
|
||||
|
||||
/**
|
||||
* The world is full.
|
||||
*/
|
||||
FULL_WORLD(7),
|
||||
|
||||
/**
|
||||
* Login server is offline.
|
||||
*/
|
||||
LOGIN_SERVER_OFFLINE(8),
|
||||
|
||||
/**
|
||||
* The login limit has been exceeded.
|
||||
*/
|
||||
LOGIN_LIMIT_EXCEEDED(9),
|
||||
|
||||
/**
|
||||
* The session key was invalid.
|
||||
*/
|
||||
BAD_SESSION_ID(10),
|
||||
|
||||
/**
|
||||
* The password is too weak, and should be improved.
|
||||
*/
|
||||
WEAK_PASSWORD(11),
|
||||
|
||||
/**
|
||||
* When trying to connect to a members world while being f2p.
|
||||
*/
|
||||
MEMBERS_WORLD(12),
|
||||
|
||||
/**
|
||||
* Could not login.
|
||||
*/
|
||||
COULD_NOT_LOGIN(13),
|
||||
|
||||
/**
|
||||
* The server is currently updating.
|
||||
*/
|
||||
UPDATING(14),
|
||||
|
||||
/**
|
||||
* Too many incorrect login attempts from your address.
|
||||
*/
|
||||
TOO_MANY_INCORRECT_LOGINS(16),
|
||||
|
||||
/**
|
||||
* When logging on a free world while standing in members area.
|
||||
*/
|
||||
STANDING_IN_MEMBER(17),
|
||||
|
||||
/**
|
||||
* This account is locked as it might have been stolen.
|
||||
*/
|
||||
LOCKED(18),
|
||||
|
||||
/**
|
||||
* Closed beta going on.
|
||||
*/
|
||||
CLOSED_BETA(19),
|
||||
|
||||
/**
|
||||
* The login server connected to is invalid.
|
||||
*/
|
||||
INVALID_LOGIN_SERVER(20),
|
||||
|
||||
/**
|
||||
* Moving from another world...
|
||||
*/
|
||||
MOVING_WORLD(21),
|
||||
|
||||
/**
|
||||
* When the player's saved file exists, but is unable to be loaded.
|
||||
*/
|
||||
ERROR_LOADING_PROFILE(24),
|
||||
|
||||
/**
|
||||
* This computer address is disabled as it was used to break our rules.
|
||||
*/
|
||||
BANNED(26);
|
||||
|
||||
/**
|
||||
* The buffer.
|
||||
*/
|
||||
private final int opcode;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Response} {@code Object}.
|
||||
* @param opcode The login response opcode.
|
||||
*/
|
||||
Response(int opcode) {
|
||||
this.opcode = opcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the opcode.
|
||||
* @return The opcode.
|
||||
*/
|
||||
public int opcode() {
|
||||
return opcode;
|
||||
}
|
||||
}
|
||||
@@ -1,224 +0,0 @@
|
||||
package ms.world.info;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import ms.system.util.ByteBufferUtils;
|
||||
|
||||
/**
|
||||
* The unique info of a player.
|
||||
* @author Vexia
|
||||
*
|
||||
*/
|
||||
public class UIDInfo {
|
||||
|
||||
/**
|
||||
* The ip address.
|
||||
*/
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* The computer name.
|
||||
*/
|
||||
private String compName;
|
||||
|
||||
/**
|
||||
* The mac-address.
|
||||
*/
|
||||
private String mac;
|
||||
|
||||
/**
|
||||
* The motherboard serial of the user.
|
||||
*/
|
||||
private String serial;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new {@code UIDInfo} {@code Object}
|
||||
*/
|
||||
public UIDInfo() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code UIDInfo} {@code Object}
|
||||
* @param ip the ip.
|
||||
* @param compName the computer name.
|
||||
* @param mac the mac.
|
||||
* @param serial the serial.
|
||||
*/
|
||||
public UIDInfo(String ip, String compName, String mac, String serial) {
|
||||
this.ip = ip;
|
||||
this.compName = compName;
|
||||
this.mac = mac;
|
||||
this.serial = serial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the data from a prepared statement.
|
||||
* @param set The result set
|
||||
* @throws SQLException The exception if thrown.
|
||||
*/
|
||||
public void parse(ResultSet set) throws SQLException {
|
||||
setIp(parseFormat(set.getString("ip")));
|
||||
setCompName(parseFormat(set.getString("computerName")));
|
||||
setMac(parseFormat(set.getString("mac")));
|
||||
setSerial(parseFormat(set.getString("serial")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the UID data on the buffer.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
public void save(ByteBuffer buffer) {
|
||||
save(buffer, ip, 1);
|
||||
save(buffer, compName, 2);
|
||||
save(buffer, mac, 3);
|
||||
save(buffer, serial, 4);
|
||||
buffer.put((byte) 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the UID data from the buffer.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
public void parse(ByteBuffer buffer) {
|
||||
int opcode;
|
||||
while ((opcode = buffer.get()) != 0) {
|
||||
switch (opcode) {
|
||||
case 1:
|
||||
ip = ByteBufferUtils.getString(buffer);
|
||||
break;
|
||||
case 2:
|
||||
compName = ByteBufferUtils.getString(buffer);
|
||||
break;
|
||||
case 3:
|
||||
mac = ByteBufferUtils.getString(buffer);
|
||||
break;
|
||||
case 4:
|
||||
serial = ByteBufferUtils.getString(buffer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string with a certain format.
|
||||
* @param string the string.
|
||||
* @return the string.
|
||||
*/
|
||||
private String parseFormat(String string) {
|
||||
if (string == null || string.equals("")) {
|
||||
return null;
|
||||
}
|
||||
StringTokenizer token = new StringTokenizer(string, "|");
|
||||
String s = "";
|
||||
int t = token.countTokens();
|
||||
for (int i = 0; i < t; i++) {
|
||||
s = token.nextToken();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a string value to the buffer.
|
||||
* @param buffer the buffer.
|
||||
* @param value the value.
|
||||
* @param opcode the opcode.
|
||||
*/
|
||||
private void save(ByteBuffer buffer, String value, int opcode) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
ByteBufferUtils.putString(value, buffer.put((byte) opcode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a to string in format mode for an admin or mod.
|
||||
* @param admin the admin.
|
||||
* @return the string.
|
||||
*/
|
||||
public String toString(boolean admin) {
|
||||
String format = toString();
|
||||
if (!admin) {//formats for non-admins
|
||||
String[] tokens = format.split("serial=");
|
||||
format = format.replace("serial=", "uid=").replace(tokens[tokens.length - 1], "*****");
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the compName.
|
||||
* @return the compName
|
||||
*/
|
||||
public String getCompName() {
|
||||
return compName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ip.
|
||||
* @return the ip
|
||||
*/
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mac.
|
||||
* @return the mac
|
||||
*/
|
||||
public String getMac() {
|
||||
return mac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the serial.
|
||||
* @return the serial
|
||||
*/
|
||||
public String getSerial() {
|
||||
return serial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ip.
|
||||
* @param ip the ip to set.
|
||||
*/
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the compName.
|
||||
* @param compName the compName to set.
|
||||
*/
|
||||
public void setCompName(String compName) {
|
||||
this.compName = compName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mac.
|
||||
* @param mac the mac to set.
|
||||
*/
|
||||
public void setMac(String mac) {
|
||||
this.mac = mac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the serial.
|
||||
* @param serial the serial to set.
|
||||
*/
|
||||
public void setSerial(String serial) {
|
||||
this.serial = serial;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[ip=" + ip + ", compName=" + compName + ", mac=" + mac + ", serial=" + serial + "]";
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
package ms.world.info;
|
||||
|
||||
/**
|
||||
* Holds the info of a world server.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class WorldInfo {
|
||||
|
||||
/**
|
||||
* The world id.
|
||||
*/
|
||||
private final int worldId;
|
||||
|
||||
/**
|
||||
* The IP-address.
|
||||
*/
|
||||
private final String address;
|
||||
|
||||
/**
|
||||
* The revision of the world.
|
||||
*/
|
||||
private final int revision;
|
||||
|
||||
/**
|
||||
* The country this world is located in.
|
||||
*/
|
||||
private final CountryFlag country;
|
||||
|
||||
/**
|
||||
* The world activity.
|
||||
*/
|
||||
private final String activity;
|
||||
|
||||
/**
|
||||
* If the world is members only.
|
||||
*/
|
||||
private final boolean members;
|
||||
|
||||
/**
|
||||
* If the world is a PvP world.
|
||||
*/
|
||||
private final boolean pvp;
|
||||
|
||||
/**
|
||||
* If the world is a quick chat only world.
|
||||
*/
|
||||
private final boolean quickChat;
|
||||
|
||||
/**
|
||||
* If the world has lootshare option enabled.
|
||||
*/
|
||||
private final boolean lootshare;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code WorldInfo} {@code Object}.
|
||||
* @param id The world id.
|
||||
* @param address The address.
|
||||
* @param country The country flag.
|
||||
* @param members If the world is members only.
|
||||
*/
|
||||
public WorldInfo(int id, String address, int revision, CountryFlag country, String activity, boolean members, boolean pvp, boolean quickChat, boolean lootshare) {
|
||||
this.worldId = id;
|
||||
this.address = address;
|
||||
this.revision = revision;
|
||||
this.country = country;
|
||||
this.activity = activity;
|
||||
this.members = members;
|
||||
this.pvp = pvp;
|
||||
this.quickChat = quickChat;
|
||||
this.lootshare = lootshare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the settings hash.
|
||||
* @return The settings hash.
|
||||
*/
|
||||
public int getSettings() {
|
||||
int settings = 0;
|
||||
if (members) {
|
||||
settings |= 0x1;
|
||||
}
|
||||
if (quickChat) {
|
||||
settings |= 0x2;
|
||||
}
|
||||
if (pvp) {
|
||||
settings |= 0x4;
|
||||
}
|
||||
if (lootshare) {
|
||||
settings |= 0x8;
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the worldId
|
||||
*/
|
||||
public int getWorldId() {
|
||||
return worldId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the address
|
||||
*/
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the country
|
||||
*/
|
||||
public CountryFlag getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the members value.
|
||||
* @return The members.
|
||||
*/
|
||||
public boolean isMembers() {
|
||||
return members;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the activity value.
|
||||
* @return The activity.
|
||||
*/
|
||||
public String getActivity() {
|
||||
return activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pvp value.
|
||||
* @return The pvp.
|
||||
*/
|
||||
public boolean isPvp() {
|
||||
return pvp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the quickChat value.
|
||||
* @return The quickChat.
|
||||
*/
|
||||
public boolean isQuickChat() {
|
||||
return quickChat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lootshare value.
|
||||
* @return The lootshare.
|
||||
*/
|
||||
public boolean isLootshare() {
|
||||
return lootshare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the revision.
|
||||
* @return the revision.
|
||||
*/
|
||||
public int getRevision() {
|
||||
return revision;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package ms09
|
||||
|
||||
import com.github.ajalt.mordant.rendering.TextColors
|
||||
import com.github.ajalt.mordant.terminal.Terminal
|
||||
import java.io.BufferedWriter
|
||||
import java.io.Writer
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
object MSLogger {
|
||||
val t = Terminal()
|
||||
var tradeLog: Writer? = null
|
||||
var tradeLogWriter: BufferedWriter? = null
|
||||
|
||||
|
||||
fun getTime(): String{
|
||||
val formatter = SimpleDateFormat("HH:mm:ss")
|
||||
return "[" + formatter.format(Date(System.currentTimeMillis())) +"]"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun logInfo(vararg messages: String){
|
||||
for(m in messages){
|
||||
if(m.isNotBlank()) t.println("${getTime()}: [INFO] $m")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun logErr(message: String){
|
||||
if(message.isNotBlank()) t.println("${getTime()}: ${TextColors.brightRed("[ ERR] $message")}")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun logWarn(message: String){
|
||||
if(message.isNotBlank()) t.println("${getTime()}: ${TextColors.yellow("[WARN] $message")}")
|
||||
}
|
||||
}
|
||||
@@ -242,6 +242,10 @@
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<useFile>false</useFile>
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
</configuration>
|
||||
<version>2.22.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
||||
+3
-3
@@ -48,7 +48,7 @@ public final class Cache {
|
||||
* @throws Throwable When an exception occurs.
|
||||
*/
|
||||
public static void init(String path) throws Throwable {
|
||||
SystemLogger.logInfo("Initializing cache...");
|
||||
SystemLogger.logInfo(Cache.class, "Initializing cache...");
|
||||
byte[] cacheFileBuffer = new byte[520];
|
||||
RandomAccessFile containersInformFile = new RandomAccessFile(path + File.separator + "main_file_cache.idx255", "r");
|
||||
RandomAccessFile dataFile = new RandomAccessFile(path + File.separator + "main_file_cache.dat2", "r");
|
||||
@@ -61,7 +61,7 @@ public final class Cache {
|
||||
CacheFile cacheFile = new CacheFile(i, new RandomAccessFile(f, "r"), dataFile, 1000000, cacheFileBuffer);
|
||||
cacheFileManagers[i] = new CacheFileManager(cacheFile, true);
|
||||
if (cacheFileManagers[i].getInformation() == null) {
|
||||
SystemLogger.logErr("Error loading cache index " + i + ": no information.");
|
||||
SystemLogger.logErr(Cache.class, "Error loading cache index " + i + ": no information.");
|
||||
cacheFileManagers[i] = null;
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,7 @@ public final class Cache {
|
||||
public static ByteBuffer getArchiveData(int index, int archive, boolean priority, int encryptionValue) {
|
||||
byte[] data = index == 255 ? referenceFile.getContainerData(archive) : cacheFileManagers[index].getCacheFile().getContainerData(archive);
|
||||
if (data == null || data.length < 1) {
|
||||
SystemLogger.logErr("Invalid JS-5 request - " + index + ", " + archive + ", " + priority + ", " + encryptionValue + "!");
|
||||
SystemLogger.logErr(Cache.class, "Invalid JS-5 request - " + index + ", " + archive + ", " + priority + ", " + encryptionValue + "!");
|
||||
return null;
|
||||
}
|
||||
int compression = data[0] & 0xff;
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ public class DataMap {
|
||||
|
||||
public int getInt(int key){
|
||||
if(!dataStore.containsKey(key)){
|
||||
SystemLogger.logErr("Invalid value passed for key: " + key + " map: " + id);
|
||||
SystemLogger.logErr(this.getClass(), "Invalid value passed for key: " + key + " map: " + id);
|
||||
return -1;
|
||||
}
|
||||
return (int) dataStore.get(key);
|
||||
|
||||
@@ -294,7 +294,7 @@ public class ItemDefinition extends Definition<Item> {
|
||||
}
|
||||
ItemDefinition def = ItemDefinition.parseDefinition(itemId, ByteBuffer.wrap(data));
|
||||
if (def == null) {
|
||||
SystemLogger.logErr("Could not load item definitions for id " + itemId + " - no definitions found!");
|
||||
SystemLogger.logErr(ItemDefinition.class, "Could not load item definitions for id " + itemId + " - no definitions found!");
|
||||
return ;
|
||||
}
|
||||
if(itemId == 14958)
|
||||
@@ -1530,7 +1530,7 @@ public class ItemDefinition extends Definition<Item> {
|
||||
ItemDefinition def = forId(nodeId);
|
||||
if (def == null) {
|
||||
if (nodeId == 22937)
|
||||
SystemLogger.logErr("[ItemDefinition] No definition for item id " + nodeId + "!");
|
||||
SystemLogger.logErr(ItemDefinition.class, "[ItemDefinition] No definition for item id " + nodeId + "!");
|
||||
return null;
|
||||
}
|
||||
OptionHandler handler = def.getConfiguration("option:" + name);
|
||||
|
||||
@@ -72,7 +72,7 @@ public class RenderAnimationDefinition {
|
||||
if (data != null) {
|
||||
defs.parse(ByteBuffer.wrap(data));
|
||||
} else {
|
||||
SystemLogger.logErr("No definitions found for render animation " + animId + ", size=" + Cache.getIndexes()[2].getFilesSize(32) + "!");
|
||||
SystemLogger.logErr(RenderAnimationDefinition.class, "No definitions found for render animation " + animId + ", size=" + Cache.getIndexes()[2].getFilesSize(32) + "!");
|
||||
}
|
||||
return defs;
|
||||
}
|
||||
|
||||
@@ -615,7 +615,7 @@ public class SceneryDefinition extends Definition<Scenery> {
|
||||
// SystemLogger.logErr("----------------------------------------------------\n\n\n");
|
||||
while (true) {
|
||||
if (!buffer.hasRemaining()) {
|
||||
SystemLogger.logErr("[ObjectDefinition] Buffer empty for " + objectId);
|
||||
SystemLogger.logErr(SceneryDefinition.class, "Buffer empty for " + objectId);
|
||||
break;
|
||||
}
|
||||
int opcode = buffer.get() & 0xFF;
|
||||
@@ -801,7 +801,7 @@ public class SceneryDefinition extends Definition<Scenery> {
|
||||
}
|
||||
} else {
|
||||
if (opcode != 0) {
|
||||
SystemLogger.logErr("Unhandled object definition opcode: " + opcode);
|
||||
SystemLogger.logErr(SceneryDefinition.class, "Unhandled object definition opcode: " + opcode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ public class Struct {
|
||||
|
||||
public int getInt(int key){
|
||||
if(!dataStore.containsKey(key)){
|
||||
SystemLogger.logErr("Invalid value passed for key: " + key + " struct: " + id);
|
||||
SystemLogger.logErr(this.getClass(), "Invalid value passed for key: " + key + " struct: " + id);
|
||||
return -1;
|
||||
}
|
||||
return (int) dataStore.get(key);
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
package core.game.component;
|
||||
|
||||
/**
|
||||
* Used to generate component option settings.
|
||||
* @author Mangis
|
||||
*/
|
||||
public final class AccessMaskBuilder {
|
||||
|
||||
/**
|
||||
* Contains the value which should be sent in access mask packet.
|
||||
*/
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Sets default option setting.
|
||||
* @param allowed If the packet for the default option should be sent to the
|
||||
* server.
|
||||
*/
|
||||
public void allowDefaultOption(boolean allowed) {
|
||||
value &= ~(0x1);
|
||||
if (allowed) {
|
||||
value |= 0x1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets right click option settings. If specified option is not allowed, it
|
||||
* will not appear in right click menu and the packet will not be send to
|
||||
* server when clicked.
|
||||
* @param optionId The option index.
|
||||
* @param show If the option is allowed.
|
||||
*/
|
||||
public void showMenuOption(int optionId, boolean show) {
|
||||
if (optionId < 0 || optionId > 9) {
|
||||
throw new IllegalArgumentException("Option index must be 0-9.");
|
||||
}
|
||||
value &= ~(0x1 << (optionId + 1));
|
||||
if (show) {
|
||||
value |= (0x1 << (optionId + 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets use on option settings. If nothing is allowed then 'use' option will
|
||||
* not appear in right click menu.
|
||||
*/
|
||||
public void setUseOnSettings(boolean groundItems, boolean npcs, boolean objects, boolean otherPlayer, boolean selfPlayer, boolean component) {
|
||||
int useFlag = 0;
|
||||
if (groundItems) {
|
||||
useFlag |= 0x1;
|
||||
}
|
||||
if (npcs) {
|
||||
useFlag |= 0x2;
|
||||
}
|
||||
if (objects) {
|
||||
useFlag |= 0x4;
|
||||
}
|
||||
if (otherPlayer) {
|
||||
useFlag |= 0x8;
|
||||
}
|
||||
if (selfPlayer) {
|
||||
useFlag |= 0x10;
|
||||
}
|
||||
if (component) {
|
||||
useFlag |= 0x20;
|
||||
}
|
||||
value &= ~(127 << 7); // disable
|
||||
value |= useFlag << 7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets interface events depth. For example, we have inventory interface
|
||||
* which is opened on gameframe interface (548) If depth is 1, then the
|
||||
* clicks in inventory will also invoke click event handler scripts on
|
||||
* gameframe interface.
|
||||
* @param depth The depth value.
|
||||
*/
|
||||
public void setInterfaceEventsDepth(int depth) {
|
||||
if (depth < 0 || depth > 7) {
|
||||
throw new IllegalArgumentException("depth must be 0-7.");
|
||||
}
|
||||
value &= ~(0x7 << 18);
|
||||
value |= (depth << 18);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags other component options being allowed to be used on this component.
|
||||
* @param allow If an option can be used on this component.
|
||||
*/
|
||||
public void allowUsage(boolean allow) {
|
||||
value &= ~(1 << 22);
|
||||
if (allow) {
|
||||
value |= (1 << 22);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value.
|
||||
* @return The value.
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
package core.game.container.access;
|
||||
|
||||
import core.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* Contains the mask value methods. The 'access mask' is actually just a bit
|
||||
* register that contains permissions for a specific interface (@Peterbjornx)
|
||||
* @date 5/02/2013
|
||||
* @author Stacx
|
||||
* @author Emperor
|
||||
* @deprecated This is a really bad way of doing what this class needs to do. Please use {@link api.IfaceSettingsBuilder}.
|
||||
*/
|
||||
@Deprecated()
|
||||
public final class BitregisterAssembler {
|
||||
|
||||
/**
|
||||
* The register size.
|
||||
*/
|
||||
public static final int SIZE = 32 - 1;
|
||||
|
||||
/**
|
||||
* Examine option.
|
||||
*/
|
||||
public static final int EXAMINE_OPT = 9;
|
||||
|
||||
/**
|
||||
* Allow dragging.
|
||||
*/
|
||||
public static final int DRAGABLE = 17;
|
||||
|
||||
/**
|
||||
* Allow switching item slots.
|
||||
*/
|
||||
public static final int SLOT_SWITCH = 20;
|
||||
|
||||
/**
|
||||
* The flags.
|
||||
*/
|
||||
private boolean[] permissions = new boolean[SIZE];
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BitregisterAssembler} {@code Object}.
|
||||
* @param permissions The permissions.
|
||||
*/
|
||||
public BitregisterAssembler(int... permissions) {
|
||||
for (int i : permissions) {
|
||||
this.permissions[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BitregisterAssembler} {@code Object}.
|
||||
*/
|
||||
public BitregisterAssembler(String[] options) {
|
||||
enableOptions(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the given options ({@code null} options will remain disabled).
|
||||
* @param options The options.
|
||||
*/
|
||||
public void enableOptions(String...options) {
|
||||
if (options.length > 9) {
|
||||
throw new IllegalStateException("Too many options specified - maximum 9 allowed!");
|
||||
}
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
if (options[i] != null && !options[i].equals("null")) {
|
||||
permissions[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the examine option.
|
||||
*/
|
||||
public void enableExamineOption() {
|
||||
permissions[EXAMINE_OPT] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables items being dragged.
|
||||
*/
|
||||
public void enableDragging() {
|
||||
permissions[DRAGABLE] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables item switching slots (& dragging).
|
||||
*/
|
||||
public void enableSlotSwitch() {
|
||||
enableDragging();
|
||||
permissions[SLOT_SWITCH] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Send</b> and assemble a bit register for our
|
||||
* @param player , the player instance
|
||||
* @param interfaceIndex , the interface index
|
||||
* @param childIndex , the child index for our interface
|
||||
* @param offset , the offset for the loop in client
|
||||
* @param length , the length of our loop
|
||||
*/
|
||||
public static void send(Player player, int interfaceIndex, int childIndex, int offset, int length, BitregisterAssembler assembler) {
|
||||
if (offset >= length) {
|
||||
throw new RuntimeException("Offset cannot excess length. length = " + length);
|
||||
}
|
||||
player.getPacketDispatch().sendIfaceSettings(assembler.calculateRegister(), childIndex, interfaceIndex, offset, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the register.
|
||||
* @return The value.
|
||||
*/
|
||||
public int calculateRegister() {
|
||||
int value = 0;
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
if (permissions[i]) {
|
||||
value |= 2 << i;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package core.game.container.access;
|
||||
|
||||
import api.IfaceSettingsBuilder;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.net.packet.PacketRepository;
|
||||
@@ -37,14 +38,16 @@ public class InterfaceContainer {
|
||||
private static int generate(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex, int x, int y, int key) {
|
||||
Object[] clientScript = new Object[options.length + 7];
|
||||
player.getPacketDispatch().sendRunScript(CLIENT_SCRIPT_INDEX, generateScriptArguments(options.length), populateScript(clientScript, options, interfaceIndex << 16 | childIndex, x, y, key));
|
||||
BitregisterAssembler.send(player, interfaceIndex, childIndex, 0, itemArray.length, new BitregisterAssembler(options));
|
||||
int settings = new IfaceSettingsBuilder().enableAllOptions().build();
|
||||
player.getPacketDispatch().sendIfaceSettings(settings, childIndex, interfaceIndex, 0, itemArray.length);
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, key, itemArray, itemArray.length, false));
|
||||
return increment();
|
||||
}
|
||||
|
||||
public static int generateOptions(Player player, String[] options, int interfaceIndex, int childIndex, int x, int y, int key){
|
||||
player.getPacketDispatch().sendRunScript(CLIENT_SCRIPT_INDEX, generateScriptArguments(options.length), populateScript(new Object[options.length + 7],options,interfaceIndex << 16 | childIndex, x, y, key));
|
||||
BitregisterAssembler.send(player,interfaceIndex,childIndex,0,28,new BitregisterAssembler(options));
|
||||
int settings = new IfaceSettingsBuilder().enableAllOptions().build();
|
||||
player.getPacketDispatch().sendIfaceSettings(settings, childIndex, interfaceIndex, 0, 28);
|
||||
return increment();
|
||||
}
|
||||
|
||||
@@ -76,7 +79,8 @@ public class InterfaceContainer {
|
||||
int key = increment();
|
||||
Object[] clientScript = new Object[options.length + 7];
|
||||
player.getPacketDispatch().sendRunScript(CLIENT_SCRIPT_INDEX, generateScriptArguments(options.length), populateScript(clientScript, options, interfaceId << 16 | childId, x, y, key));
|
||||
BitregisterAssembler.send(player, interfaceId, childId, 0, itemLength, new BitregisterAssembler(options));
|
||||
int settings = new IfaceSettingsBuilder().enableAllOptions().build();
|
||||
player.getPacketDispatch().sendIfaceSettings(settings, childId, interfaceId, 0, itemLength);
|
||||
return key;
|
||||
}
|
||||
|
||||
@@ -125,7 +129,6 @@ public class InterfaceContainer {
|
||||
/**
|
||||
* Default method to generate and send an item array for the client.
|
||||
* @return The container key.
|
||||
* @see {@link InterfaceContainer.generate}
|
||||
*/
|
||||
public static int generateItems(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex) {
|
||||
return generateItems(player, itemArray, options, interfaceIndex, childIndex, 7, 3, increment());
|
||||
@@ -134,7 +137,6 @@ public class InterfaceContainer {
|
||||
/**
|
||||
* Default method to generate and send an item array for the client.
|
||||
* @return The container key.
|
||||
* @see {@link InterfaceContainer.generate}
|
||||
*/
|
||||
public static int generateItems(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex, int key) {
|
||||
return generateItems(player, itemArray, options, interfaceIndex, childIndex, 7, 3, key);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package core.game.container.impl;
|
||||
|
||||
import api.IfaceSettingsBuilder;
|
||||
import core.game.container.access.InterfaceContainer;
|
||||
import kotlin.ranges.IntRange;
|
||||
import org.rs09.consts.Vars;
|
||||
import rs09.ServerConstants;
|
||||
import core.game.component.Component;
|
||||
import core.game.container.*;
|
||||
import core.game.container.access.BitregisterAssembler;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.link.IronmanMode;
|
||||
import core.game.node.item.Item;
|
||||
@@ -128,10 +129,8 @@ public final class BankContainer extends Container {
|
||||
player.getInventory().getListeners().add(listener);
|
||||
player.getInventory().refresh();
|
||||
player.varpManager.get(1249).setVarbit(0,lastAmountX).send(player);
|
||||
BitregisterAssembler assembly = new BitregisterAssembler(0, 1, 2, 3, 4, 5);
|
||||
assembly.enableExamineOption();
|
||||
assembly.enableSlotSwitch();
|
||||
player.getPacketDispatch().sendIfaceSettings(assembly.calculateRegister(), 0, 763, 0, 27);
|
||||
int settings = new IfaceSettingsBuilder().enableOptions(new IntRange(0, 5)).enableExamine().enableSlotSwitch().build();
|
||||
player.getPacketDispatch().sendIfaceSettings(settings, 0, 763, 0, 27);
|
||||
player.getPacketDispatch().sendRunScript(1451, "");
|
||||
open = true;
|
||||
setTabConfigurations();
|
||||
@@ -159,10 +158,8 @@ public final class BankContainer extends Container {
|
||||
player.getInventory().refresh();
|
||||
player.varpManager.get(1249).setVarbit(0,lastAmountX).send(player);
|
||||
player.getPacketDispatch().sendIfaceSettings(1278, 73, 762, 0, SIZE);
|
||||
BitregisterAssembler assembly = new BitregisterAssembler(0, 1, 2, 3, 4, 5);
|
||||
assembly.enableExamineOption();
|
||||
assembly.enableSlotSwitch();
|
||||
player.getPacketDispatch().sendIfaceSettings(assembly.calculateRegister(), 0, 763, 0, 27);
|
||||
int settings = new IfaceSettingsBuilder().enableOptions(new IntRange(0,5)).enableExamine().enableSlotSwitch().build();
|
||||
player.getPacketDispatch().sendIfaceSettings(settings, 0, 763, 0, 27);
|
||||
player.getPacketDispatch().sendRunScript(1451, "");
|
||||
open = true;
|
||||
this.player.getBank().setTabConfigurations(player);
|
||||
|
||||
@@ -50,7 +50,7 @@ public final class ActivityManager {
|
||||
ActivityPlugin plugin = ACTIVITIES.get(name);
|
||||
if (plugin == null) {
|
||||
if (GameWorld.getSettings().isDevMode()) {
|
||||
SystemLogger.logErr("Unhandled activity - " + name + "!");
|
||||
SystemLogger.logErr(ActivityManager.class, "Unhandled activity - " + name + "!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -368,7 +368,7 @@ public final class GodwarsMapzone extends MapZone implements Plugin<Object> {
|
||||
}
|
||||
|
||||
if (DoorActionHandler.handleAutowalkDoor(player, object)) {
|
||||
SystemLogger.logInfo(player.getUsername() + " entered " + faction.name() + " gwd boss room");
|
||||
SystemLogger.logInfo(this.getClass(), player.getUsername() + " entered " + faction.name() + " gwd boss room");
|
||||
increaseKillcount(player, faction, -required);
|
||||
}
|
||||
return true;
|
||||
|
||||
+1
-1
@@ -128,7 +128,7 @@ public class GuardDialoguePlugin extends DialoguePlugin {
|
||||
stage = -1;
|
||||
break;
|
||||
default:
|
||||
SystemLogger.logErr("Unhandled dialogue stage=" + stage);
|
||||
SystemLogger.logErr(this.getClass(), "Unhandled dialogue stage=" + stage);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ public abstract class DialoguePlugin implements Plugin<Player> {
|
||||
}
|
||||
|
||||
if (npc == null) {
|
||||
SystemLogger.logWarn(
|
||||
SystemLogger.logWarn(this.getClass(),
|
||||
args[0].getClass().getSimpleName() +
|
||||
"Is not assigning an NPC. Whoever did that should fix it."
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package core.game.content.global.action;
|
||||
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.system.communication.CommunicationInfo;
|
||||
import rs09.game.interaction.SpadeDigListener;
|
||||
import rs09.game.system.SystemLogger;
|
||||
import core.game.system.task.Pulse;
|
||||
@@ -62,7 +63,7 @@ public final class DigSpadeHandler {
|
||||
*/
|
||||
public static boolean register(Location location, DigAction action) {
|
||||
if (ACTIONS.containsKey(location)) {
|
||||
SystemLogger.logErr("Already contained dig reward for location " + location + ".");
|
||||
SystemLogger.logErr(CommunicationInfo.class, "Already contained dig reward for location " + location + ".");
|
||||
return false;
|
||||
}
|
||||
ACTIONS.put(location, action);
|
||||
|
||||
@@ -49,7 +49,7 @@ public final class DropItemHandler {
|
||||
return false;
|
||||
}
|
||||
if (player.getAttribute("equipLock:" + item.getId(), 0) > GameWorld.getTicks()) {
|
||||
SystemLogger.logAlert(player + ", tried to do the drop & equip dupe.");
|
||||
SystemLogger.logAlert(DropItemHandler.class, player + ", tried to do the drop & equip dupe.");
|
||||
return true;
|
||||
}
|
||||
if (player.getInventory().replace(null, item.getSlot()) == item) {
|
||||
|
||||
@@ -119,7 +119,7 @@ public abstract class HolidayEvent extends MapZone implements Plugin<Object> {
|
||||
if (isActive()) {
|
||||
setCurrent(this);
|
||||
ZoneBuilder.configure(this);
|
||||
SystemLogger.logInfo("Holiday event active [type=" + type + "]!");
|
||||
SystemLogger.logInfo(this.getClass(), "Holiday event active [type=" + type + "]!");
|
||||
}
|
||||
EVENTS.add(this);
|
||||
return this;
|
||||
|
||||
-1
@@ -1,7 +1,6 @@
|
||||
package core.game.content.quest.free.therestlessghost;
|
||||
|
||||
import core.game.component.Component;
|
||||
import core.game.container.access.BitregisterAssembler;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.link.diary.DiaryType;
|
||||
import core.plugin.Initializable;
|
||||
|
||||
+1
-1
@@ -289,7 +289,7 @@ public class DwarfCannonPlugin extends OptionHandler {
|
||||
}
|
||||
Part part = Part.forId(button);
|
||||
if (part == null) {
|
||||
SystemLogger.logErr("Unhandled part id - " + button + "!");
|
||||
SystemLogger.logErr(this.getClass(), "Unhandled part id - " + button + "!");
|
||||
return true;
|
||||
}
|
||||
if (this.tool.getPart() != part) {
|
||||
|
||||
@@ -138,7 +138,7 @@ public abstract class ClueScrollPlugin extends MapZone implements Plugin<Object>
|
||||
if(clue.getClueId() == 2681)
|
||||
return;
|
||||
if (CLUE_SCROLLS.containsKey(clue.getClueId())) {
|
||||
SystemLogger.logErr("Error! Plugin already registered with clue id - " + clue.getClueId() + ", trying to register " + clue.getClass().getCanonicalName() + " the real plugin using the id is " + CLUE_SCROLLS.get(clue.getClueId()).getClass().getCanonicalName() + "!");
|
||||
SystemLogger.logErr(this.getClass(), "Error! Plugin already registered with clue id - " + clue.getClueId() + ", trying to register " + clue.getClass().getCanonicalName() + " the real plugin using the id is " + CLUE_SCROLLS.get(clue.getClueId()).getClass().getCanonicalName() + "!");
|
||||
return;
|
||||
}
|
||||
List<ClueScrollPlugin> organized = (List<ClueScrollPlugin>) ORGANIZED.get(clue.getLevel());
|
||||
@@ -169,7 +169,7 @@ public abstract class ClueScrollPlugin extends MapZone implements Plugin<Object>
|
||||
public static Item getClue(ClueLevel clueLevel) {
|
||||
List<ClueScrollPlugin> clues = ORGANIZED.get(clueLevel);
|
||||
if (clues == null) {
|
||||
SystemLogger.logErr("Error! There are no clues for level " + clueLevel + "!");
|
||||
SystemLogger.logErr(ClueScrollPlugin.class, "Error! There are no clues for level " + clueLevel + "!");
|
||||
return null;
|
||||
}
|
||||
ClueScrollPlugin clue = clues.get(RandomFunction.random(clues.size()));
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
package core.game.ge;
|
||||
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
import rs09.game.system.config.ItemConfigParser;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Handles the buying limitations.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class BuyingLimitation {
|
||||
|
||||
/**
|
||||
* Mapping holding buying amounts per player for every item id.
|
||||
*/
|
||||
private static final Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BuyingLimitation} {@code Object}.
|
||||
*/
|
||||
private BuyingLimitation() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum amount the player can buy of this item.
|
||||
* @param itemId The item id.
|
||||
* @param playerUID The player UID.
|
||||
* @return The maximum amount to buy.
|
||||
*/
|
||||
public static int getMaximumBuy(int itemId, int playerUID) {
|
||||
Map<Integer, Integer> data = CACHE.get(itemId);
|
||||
Integer current = 0;
|
||||
if (data != null) {
|
||||
current = data.get(playerUID);
|
||||
}
|
||||
if (current == null) {
|
||||
current = 0;
|
||||
}
|
||||
return ItemDefinition.forId(itemId).getConfiguration(ItemConfigParser.GE_LIMIT, 25000) - current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the currently bought amount.
|
||||
* @param itemId The item id.
|
||||
* @param playerUID The player UID.
|
||||
* @param amount The amount.
|
||||
*/
|
||||
public static void updateBoughtAmount(int itemId, int playerUID, int amount) {
|
||||
Map<Integer, Integer> data = CACHE.get(itemId);
|
||||
if (data == null) {
|
||||
CACHE.put(itemId, data = new HashMap<>());
|
||||
}
|
||||
Integer current = data.get(playerUID);
|
||||
if (current == null) {
|
||||
current = 0;
|
||||
}
|
||||
current += amount;
|
||||
data.put(playerUID, current);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the offer is limited.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean isLimited(int itemId, int playerUID) {
|
||||
Map<Integer, Integer> data = CACHE.get(itemId);
|
||||
if (data == null) {
|
||||
return false;
|
||||
}
|
||||
Integer current = data.get(playerUID);
|
||||
if (current == null) {
|
||||
return false;
|
||||
}
|
||||
int max = ItemDefinition.forId(itemId).getConfiguration(ItemConfigParser.GE_LIMIT, 25000);
|
||||
return current >= max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cached data.
|
||||
*/
|
||||
public static void clear() {
|
||||
CACHE.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
package core.game.ge;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a grand exchange entry, which contains the item id, current price
|
||||
* and previous prices.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class GrandExchangeEntry {
|
||||
|
||||
/**
|
||||
* The item id.
|
||||
*/
|
||||
private final int itemId;
|
||||
|
||||
/**
|
||||
* The item value.
|
||||
*/
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* The value log.
|
||||
*/
|
||||
private int[] valueLog = new int[256];
|
||||
|
||||
/**
|
||||
* The log length.
|
||||
*/
|
||||
private int logLength;
|
||||
|
||||
/**
|
||||
* The amount of unique trades completed.
|
||||
*/
|
||||
private int uniqueTrades;
|
||||
|
||||
/**
|
||||
* The total value amount of each the unique trades. <br> This is used to
|
||||
* calculate the average price, so we know whether or not to update price.
|
||||
*/
|
||||
private long totalValue;
|
||||
|
||||
/**
|
||||
* The last update time stamp.
|
||||
*/
|
||||
private long lastUpdate;
|
||||
|
||||
/**
|
||||
* The mapping of completed buying offers.
|
||||
*/
|
||||
private Map<Integer, Integer> boughtMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GrandExchangeEntry} {@code Object}.
|
||||
* @param itemId The item id.
|
||||
*/
|
||||
public GrandExchangeEntry(int itemId) {
|
||||
this.itemId = itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the item value.
|
||||
* @param value The new item value to set.
|
||||
*/
|
||||
public void updateValue(int value) {
|
||||
int[] newValueLog = new int[256];
|
||||
System.arraycopy(valueLog, 0, newValueLog, 1, logLength);
|
||||
newValueLog[0] = this.value;
|
||||
this.valueLog = newValueLog;
|
||||
this.value = value;
|
||||
this.uniqueTrades = 0;
|
||||
this.totalValue = 0;
|
||||
if (++logLength > 255) {
|
||||
logLength = 255;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Influences the price of this item.
|
||||
* @param value The value offered in the exchange.
|
||||
*/
|
||||
public void influenceValue(int value) {
|
||||
if (value < this.value * 0.5) { // Makes sure the player can't influence
|
||||
// too much
|
||||
value = (int) (this.value * 0.5);
|
||||
} else if (value > this.value * 1.5) {
|
||||
value = (int) (this.value * 1.5);
|
||||
}
|
||||
uniqueTrades++;
|
||||
totalValue += value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the itemId.
|
||||
* @return The itemId.
|
||||
*/
|
||||
public int getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value.
|
||||
* @return The value.
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value.
|
||||
* @param value The value to set.
|
||||
*/
|
||||
public void setValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the valueLog.
|
||||
* @return The valueLog.
|
||||
*/
|
||||
public int[] getValueLog() {
|
||||
return valueLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the valueLog.
|
||||
* @param valueLog The valueLog to set.
|
||||
*/
|
||||
public void setValueLog(int[] valueLog) {
|
||||
this.valueLog = valueLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the uniqueTrades.
|
||||
* @return The uniqueTrades.
|
||||
*/
|
||||
public int getUniqueTrades() {
|
||||
return uniqueTrades;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the uniqueTrades.
|
||||
* @param uniqueTrades The uniqueTrades to set.
|
||||
*/
|
||||
public void setUniqueTrades(int uniqueTrades) {
|
||||
this.uniqueTrades = uniqueTrades;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the totalValue.
|
||||
* @return The totalValue.
|
||||
*/
|
||||
public long getTotalValue() {
|
||||
return totalValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the totalValue.
|
||||
* @param totalValue The totalValue to set.
|
||||
*/
|
||||
public void setTotalValue(long totalValue) {
|
||||
this.totalValue = totalValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lastUpdate.
|
||||
* @return The lastUpdate.
|
||||
*/
|
||||
public long getLastUpdate() {
|
||||
return lastUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lastUpdate.
|
||||
* @param lastUpdate The lastUpdate to set.
|
||||
*/
|
||||
public void setLastUpdate(long lastUpdate) {
|
||||
this.lastUpdate = lastUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the logLength.
|
||||
* @return The logLength.
|
||||
*/
|
||||
public int getLogLength() {
|
||||
return logLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logLength.
|
||||
* @param logLength The logLength to set.
|
||||
*/
|
||||
public void setLogLength(int logLength) {
|
||||
this.logLength = logLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the boughtMap.
|
||||
* @return The boughtMap.
|
||||
*/
|
||||
public Map<Integer, Integer> getBoughtMap() {
|
||||
return boughtMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the boughtMap.
|
||||
* @param boughtMap The boughtMap to set.
|
||||
*/
|
||||
public void setBoughtMap(Map<Integer, Integer> boughtMap) {
|
||||
this.boughtMap = boughtMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GrandExchangeEntry [itemId=" + itemId + ", value=" + value + ", valueLog=" + Arrays.toString(valueLog) + ", logLength=" + logLength + ", uniqueTrades=" + uniqueTrades + ", totalValue=" + totalValue + ", lastUpdate=" + lastUpdate + ", boughtMap=" + boughtMap + "]";
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import core.game.world.update.flag.player.FaceLocationFlag;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.InteractionOptionContext;
|
||||
import core.net.packet.out.InteractionOption;
|
||||
import rs09.game.interaction.IntType;
|
||||
import rs09.game.interaction.InteractionListeners;
|
||||
import rs09.game.system.SystemLogger;
|
||||
import rs09.game.world.GameWorld;
|
||||
@@ -86,7 +87,7 @@ public class Interaction {
|
||||
player.dispatch(new InteractionEvent(node, option.getName().toLowerCase()));
|
||||
} catch (Exception e){
|
||||
e.printStackTrace();
|
||||
SystemLogger.logErr(this.getClass().getName() + e.getMessage());
|
||||
SystemLogger.logErr(this.getClass(), this.getClass().getName() + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +109,7 @@ public class Interaction {
|
||||
if (player.getLocks().isInteractionLocked() || player.getZoneMonitor().interact(node, option)) {
|
||||
return true;
|
||||
}
|
||||
if(InteractionListeners.run(node.getId(),0,option.getName(),player,node)){
|
||||
if(InteractionListeners.run(node.getId(), IntType.ITEM, option.getName(),player,node)){
|
||||
return true;
|
||||
}
|
||||
if (option.getHandler() == null || !option.getHandler().handle(player, node, option.getName().toLowerCase())) {
|
||||
@@ -119,7 +120,7 @@ public class Interaction {
|
||||
}
|
||||
} catch (Exception e){
|
||||
e.printStackTrace();
|
||||
SystemLogger.logErr(this.getClass().getName() + e.getMessage());
|
||||
SystemLogger.logErr(this.getClass(), this.getClass().getName() + e.getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -150,7 +151,7 @@ public class Interaction {
|
||||
player.getPacketDispatch().sendMessage("Nothing interesting happens.");
|
||||
} catch (Exception e){
|
||||
e.printStackTrace();
|
||||
SystemLogger.logErr(this.getClass().getName() + e.getMessage());
|
||||
SystemLogger.logErr(this.getClass(), this.getClass().getName() + e.getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -188,7 +189,7 @@ public class Interaction {
|
||||
}
|
||||
} catch (Exception e){
|
||||
e.printStackTrace();
|
||||
SystemLogger.logErr(this.getClass().getName() + e.getMessage());
|
||||
SystemLogger.logErr(this.getClass(), this.getClass().getName() + e.getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -233,9 +233,9 @@ public abstract class MovementPulse extends Pulse {
|
||||
return;
|
||||
}
|
||||
if(destination.getLocation() == null){
|
||||
SystemLogger.logAlert(destination.getId() + " < ID");
|
||||
SystemLogger.logAlert(destination.getName() + " < NAME");
|
||||
SystemLogger.logAlert("ASDAD");
|
||||
SystemLogger.logAlert(this.getClass(), destination.getId() + " < ID");
|
||||
SystemLogger.logAlert(this.getClass(), destination.getName() + " < NAME");
|
||||
SystemLogger.logAlert(this.getClass(), "ASDAD");
|
||||
return;
|
||||
}
|
||||
boolean inside = isInsideEntity(mover.getLocation());
|
||||
|
||||
@@ -71,7 +71,7 @@ public abstract class OptionHandler implements Plugin<Object> {
|
||||
final SceneryDefinition definition = SceneryDefinition.forId(wrapper);
|
||||
final List<Integer> list = new ArrayList<>(20);
|
||||
if (definition.getChildrenIds() == null) {
|
||||
SystemLogger.logErr("Null child wrapper in option handler wrapperId=" + wrapper);
|
||||
SystemLogger.logErr(this.getClass(), "Null child wrapper in option handler wrapperId=" + wrapper);
|
||||
return new int[] { wrapper };
|
||||
}
|
||||
for (int child : definition.getChildrenIds()) {
|
||||
|
||||
@@ -210,7 +210,7 @@ public abstract class UseWithHandler implements Plugin<Object> {
|
||||
final SceneryDefinition definition = SceneryDefinition.forId(wrapper);
|
||||
final List<Integer> list = new ArrayList<>(20);
|
||||
if (definition.getChildrenIds() == null) {
|
||||
SystemLogger.logErr("Null child wrapper in option handler wrapperId=" + wrapper);
|
||||
SystemLogger.logErr(this.getClass(), "Null child wrapper in option handler wrapperId=" + wrapper);
|
||||
return new int[]{wrapper};
|
||||
}
|
||||
for (int child : definition.getChildrenIds()) {
|
||||
|
||||
@@ -7,7 +7,6 @@ import core.game.component.ComponentPlugin;
|
||||
import core.game.container.Container;
|
||||
import core.game.container.ContainerEvent;
|
||||
import core.game.container.ContainerListener;
|
||||
import core.game.container.access.BitregisterAssembler;
|
||||
import core.game.container.access.InterfaceContainer;
|
||||
import core.game.container.impl.EquipmentContainer;
|
||||
import core.game.interaction.OptionHandler;
|
||||
@@ -22,6 +21,7 @@ import core.net.packet.out.ContainerPacket;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import rs09.game.content.global.action.EquipHandler;
|
||||
import rs09.game.interaction.IntType;
|
||||
import rs09.game.interaction.InteractionListeners;
|
||||
import rs09.game.world.GameWorld;
|
||||
|
||||
@@ -82,7 +82,7 @@ public final class EquipmentInterface extends ComponentPlugin {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
if (item == null) return true;
|
||||
InteractionListeners.run(item.getId(),0,"equip",p, item);
|
||||
InteractionListeners.run(item.getId(), IntType.ITEM,"equip",p, item);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -164,10 +164,6 @@ public final class EquipmentInterface extends ComponentPlugin {
|
||||
EquipmentContainer.update(p);
|
||||
p.getInterfaceManager().openSingleTab(new Component(670));
|
||||
InterfaceContainer.generateItems(p, p.getInventory().toArray(), new String[] { "Equip" }, 670, 0, 7, 4, 93);
|
||||
BitregisterAssembler assembly = new BitregisterAssembler(new String[] { "Equip" });
|
||||
assembly.enableExamineOption();
|
||||
assembly.enableSlotSwitch();
|
||||
p.getPacketDispatch().sendIfaceSettings(assembly.calculateRegister(), 0, 670, 0, 27);
|
||||
p.getInventory().getListeners().add(listener);
|
||||
p.getInventory().refresh();
|
||||
ItemDefinition.statsUpdate(p);
|
||||
@@ -192,7 +188,7 @@ public final class EquipmentInterface extends ComponentPlugin {
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
if(InteractionListeners.run(item.getId(),0,"operate",player,item)){
|
||||
if(InteractionListeners.run(item.getId(),IntType.ITEM,"operate",player,item)){
|
||||
return;
|
||||
}
|
||||
OptionHandler handler = item.getOperateHandler();
|
||||
|
||||
@@ -31,7 +31,7 @@ public final class WorldMapInterface extends ComponentPlugin {
|
||||
player.updateSceneGraph(true);
|
||||
return true;
|
||||
default:
|
||||
//SystemLogger.logErr("World map: buttonid: " + button + ", opcode: " + opcode + ", slot: " + slot);
|
||||
//SystemLogger.logErr(this.getClass(), "World map: buttonid: " + button + ", opcode: " + opcode + ", slot: " + slot);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
package core.game.interaction.item
|
||||
|
||||
import api.*
|
||||
import core.Util
|
||||
import core.cache.def.impl.ItemDefinition
|
||||
import core.plugin.Initializable
|
||||
import core.game.interaction.OptionHandler
|
||||
import core.plugin.Plugin
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.interaction.item.ExplorersRingPlugin
|
||||
import core.game.node.Node
|
||||
import api.hasLevelStat
|
||||
import api.sendMessage
|
||||
import api.teleport
|
||||
import api.visualize
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.TeleportManager.TeleportType
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.json.simple.JSONObject
|
||||
import org.rs09.consts.Items
|
||||
import rs09.ServerStore
|
||||
import rs09.ServerStore.Companion.getBoolean
|
||||
import rs09.ServerStore.Companion.getInt
|
||||
import rs09.game.interaction.IntType
|
||||
import rs09.game.interaction.InteractionListener
|
||||
|
||||
/**
|
||||
@@ -33,7 +28,7 @@ class ExplorersRingPlugin : InteractionListener {
|
||||
|
||||
|
||||
override fun defineListeners() {
|
||||
on(RINGS, ITEM, "run-replenish"){player, node ->
|
||||
on(RINGS, IntType.ITEM, "run-replenish"){player, node ->
|
||||
val charges = getStoreFile().getInt(player.username.toLowerCase() + ":run")
|
||||
if (charges >= getRingLevel(node.id)) {
|
||||
sendMessage(player,"You have used all the charges you can for one day.")
|
||||
@@ -49,7 +44,7 @@ class ExplorersRingPlugin : InteractionListener {
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(RINGS, ITEM, "low-alchemy"){player, _ ->
|
||||
on(RINGS, IntType.ITEM, "low-alchemy"){player, _ ->
|
||||
if (!hasLevelStat(player, Skills.MAGIC, 21)) {
|
||||
sendMessage(player,"You need a Magic level of 21 in order to do that.")
|
||||
return@on true
|
||||
@@ -65,12 +60,12 @@ class ExplorersRingPlugin : InteractionListener {
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(RINGS, ITEM, "cabbage-port"){player, node ->
|
||||
on(RINGS, IntType.ITEM, "cabbage-port"){player, node ->
|
||||
teleport(player)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(RINGS, ITEM, "operate", "rub"){player, node ->
|
||||
on(RINGS, IntType.ITEM, "operate", "rub"){player, node ->
|
||||
if(getRingLevel(node.id) < 3){
|
||||
sendMessage(player, "This item can not be operated.")
|
||||
return@on true
|
||||
|
||||
@@ -5,6 +5,7 @@ import api.openBankAccount
|
||||
import core.game.content.global.shop.CulinomancerShop
|
||||
import org.rs09.consts.Scenery
|
||||
import rs09.game.interaction.InteractionListener
|
||||
import rs09.game.interaction.IntType
|
||||
|
||||
/**
|
||||
* Handles the culino chest options.
|
||||
@@ -16,12 +17,12 @@ class CulinoChestListener : InteractionListener {
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
on(CULINO_CHEST, SCENERY, "buy-items", "buy-food"){player, _ ->
|
||||
on(CULINO_CHEST, IntType.SCENERY, "buy-items", "buy-food"){player, _ ->
|
||||
CulinomancerShop.openShop(player, food = getUsedOption(player).lowercase() == "buy-food")
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(CULINO_CHEST, SCENERY, "bank"){player, _ ->
|
||||
on(CULINO_CHEST, IntType.SCENERY, "bank"){player, _ ->
|
||||
openBankAccount(player)
|
||||
return@on true
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import core.net.packet.context.MinimapStateContext
|
||||
import core.net.packet.out.MinimapState
|
||||
import core.tools.RandomFunction
|
||||
import rs09.game.interaction.InteractionListener
|
||||
import rs09.game.interaction.IntType
|
||||
import rs09.game.world.GameWorld
|
||||
import rs09.plugin.ClassScanner
|
||||
|
||||
@@ -39,7 +40,7 @@ class GardenObjectsPlugin : InteractionListener {
|
||||
SqirkMakingDialogue().init()
|
||||
ClassScanner.definePlugin(SorceressGardenObject())
|
||||
|
||||
on(SQIRK_TREES, SCENERY, "pick-fruit"){player, node ->
|
||||
on(SQIRK_TREES, IntType.SCENERY, "pick-fruit"){player, node ->
|
||||
val def = SeasonDefinitions.forTreeId(node.id)
|
||||
if (def != null) {
|
||||
player.lock()
|
||||
@@ -73,7 +74,7 @@ class GardenObjectsPlugin : InteractionListener {
|
||||
}
|
||||
|
||||
|
||||
on(FOUNTAIN, SCENERY, "drink-from"){player, _ ->
|
||||
on(FOUNTAIN, IntType.SCENERY, "drink-from"){player, _ ->
|
||||
player.lock()
|
||||
GameWorld.Pulser.submit(object : Pulse(1, player) {
|
||||
var counter = 0
|
||||
@@ -101,7 +102,7 @@ class GardenObjectsPlugin : InteractionListener {
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(SHELVES, SCENERY, "search"){player, node ->
|
||||
on(SHELVES, IntType.SCENERY, "search"){player, node ->
|
||||
if (player.inventory.freeSlots() < 1) {
|
||||
player.sendMessage("You don't have enough space in your inventory to take a beer glass.")
|
||||
} else {
|
||||
@@ -112,7 +113,7 @@ class GardenObjectsPlugin : InteractionListener {
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(HERBS, SCENERY, "pick"){player, node ->
|
||||
on(HERBS, IntType.SCENERY, "pick"){player, node ->
|
||||
val herbDef = HerbDefinition.forId(node.getId())
|
||||
if (herbDef != null) {
|
||||
handleElementalGarden(player, node.asScenery(), herbDef)
|
||||
|
||||
@@ -63,7 +63,7 @@ public abstract class AbstractNPC extends NPC implements Plugin<Object> {
|
||||
if (mapping.containsKey(id)) {
|
||||
String name = mapping.get(id).getClass().getSimpleName();
|
||||
if (name != getClass().getSimpleName()) {
|
||||
SystemLogger.logErr("[" + getClass().getSimpleName() + "] - Warning: Mapping already contained NPC id " + id + "! (" + name + ")");
|
||||
SystemLogger.logErr(this.getClass(), "[" + getClass().getSimpleName() + "] - Warning: Mapping already contained NPC id " + id + "! (" + name + ")");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,11 +57,11 @@ public final class CELEMinorTable implements StartupListener {
|
||||
@Override
|
||||
public void startup() {
|
||||
if(ServerConstants.CELEDT_DATA_PATH != null && !new File(ServerConstants.CELEDT_DATA_PATH).exists()){
|
||||
SystemLogger.logErr("Can't locate CELEDT file at " + ServerConstants.CELEDT_DATA_PATH);
|
||||
SystemLogger.logErr(this.getClass(), "Can't locate CELEDT file at " + ServerConstants.CELEDT_DATA_PATH);
|
||||
return;
|
||||
}
|
||||
parse(ServerConstants.CELEDT_DATA_PATH);
|
||||
logInfo("Loaded up Chaos Elemental drop table from " + ServerConstants.CELEDT_DATA_PATH);
|
||||
logInfo(this.getClass(), "Loaded up Chaos Elemental drop table from " + ServerConstants.CELEDT_DATA_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -57,11 +57,11 @@ public final class RareDropTable implements StartupListener {
|
||||
@Override
|
||||
public void startup() {
|
||||
if(ServerConstants.RDT_DATA_PATH != null && !new File(ServerConstants.RDT_DATA_PATH).exists()){
|
||||
SystemLogger.logErr("Can't locate RDT file at " + ServerConstants.RDT_DATA_PATH);
|
||||
SystemLogger.logErr(this.getClass(), "Can't locate RDT file at " + ServerConstants.RDT_DATA_PATH);
|
||||
return;
|
||||
}
|
||||
parse(ServerConstants.RDT_DATA_PATH);
|
||||
logInfo("Initialized Rare Drop Table from " + ServerConstants.RDT_DATA_PATH);
|
||||
logInfo(this.getClass(), "Initialized Rare Drop Table from " + ServerConstants.RDT_DATA_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -341,7 +341,7 @@ public class Player extends Entity {
|
||||
@Override
|
||||
public void init() {
|
||||
if(!artificial)
|
||||
SystemLogger.logInfo(getUsername() + " initialising...");
|
||||
SystemLogger.logInfo(this.getClass(), getUsername() + " initialising...");
|
||||
if (!artificial) {
|
||||
getProperties().setSpawnLocation(ServerConstants.HOME_LOCATION);
|
||||
getDetails().getSession().setObject(this);
|
||||
|
||||
+2
-2
@@ -210,7 +210,7 @@ public final class LoginConfiguration {
|
||||
*/
|
||||
public static final void config(final Player player) {
|
||||
if(!player.isArtificial())
|
||||
SystemLogger.logInfo("configuring player " + player.getUsername());
|
||||
SystemLogger.logInfo(LoginConfiguration.class, "configuring player " + player.getUsername());
|
||||
player.getInventory().refresh();
|
||||
player.getEquipment().refresh();
|
||||
player.getSkills().refresh();
|
||||
@@ -227,7 +227,7 @@ public final class LoginConfiguration {
|
||||
player.getEmoteManager().refresh();
|
||||
player.getInterfaceManager().openInfoBars();
|
||||
if(!player.isArtificial())
|
||||
SystemLogger.logInfo("finished configuring player " + player.getUsername());
|
||||
SystemLogger.logInfo(LoginConfiguration.class, "finished configuring player " + player.getUsername());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,7 +60,7 @@ public final class PlayerParser {
|
||||
assert os != null;
|
||||
os.close();
|
||||
} catch (Exception f){
|
||||
SystemLogger.logWarn("Unable to close file copiers in PlayerParser.java line 216.");
|
||||
SystemLogger.logWarn(PlayerParser.class, "Unable to close file copiers in PlayerParser.java line 216.");
|
||||
f.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ public final class InterfaceManager {
|
||||
public Component openWindowsPane(Component windowsPane, boolean overlap) {
|
||||
this.windowsPane = windowsPane;
|
||||
if (windowsPane.getDefinition().getType() != InterfaceType.WINDOW_PANE) {
|
||||
SystemLogger.logErr("Set interface type to WINDOW_PANE for component " + windowsPane.getId() + ", definition requires updating!");
|
||||
SystemLogger.logErr(this.getClass(), "Set interface type to WINDOW_PANE for component " + windowsPane.getId() + ", definition requires updating!");
|
||||
windowsPane.getDefinition().setType(InterfaceType.WINDOW_PANE);
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ public final class InterfaceManager {
|
||||
public void openWindowsPane(Component windowsPane, int type) {
|
||||
this.windowsPane = windowsPane;
|
||||
if (windowsPane.getDefinition().getType() != InterfaceType.WINDOW_PANE) {
|
||||
SystemLogger.logErr("Set interface type to WINDOW_PANE for component " + windowsPane.getId() + ", definition requires updating!");
|
||||
SystemLogger.logErr(this.getClass(), "Set interface type to WINDOW_PANE for component " + windowsPane.getId() + ", definition requires updating!");
|
||||
windowsPane.getDefinition().setType(InterfaceType.SINGLE_TAB);
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ public final class InterfaceManager {
|
||||
*/
|
||||
public Component openSingleTab(Component component) {
|
||||
if (component.getDefinition().getType() != InterfaceType.SINGLE_TAB) {
|
||||
SystemLogger.logErr("Set interface type to SINGLE_TAB for component " + component.getId() + ", definition requires updating!");
|
||||
SystemLogger.logErr(this.getClass(), "Set interface type to SINGLE_TAB for component " + component.getId() + ", definition requires updating!");
|
||||
component.getDefinition().setType(InterfaceType.SINGLE_TAB);
|
||||
}
|
||||
component.open(player);
|
||||
@@ -453,11 +453,11 @@ public final class InterfaceManager {
|
||||
throw new IllegalStateException("Attack tab can only be instanced as " + WeaponInterface.class.getCanonicalName() + "!");
|
||||
}
|
||||
if (component.getDefinition().getTabIndex() != slot) {
|
||||
SystemLogger.logErr("Set tab index to " + slot + " for component " + component.getId() + ", definition requires updating!");
|
||||
SystemLogger.logErr(this.getClass(), "Set tab index to " + slot + " for component " + component.getId() + ", definition requires updating!");
|
||||
component.getDefinition().setTabIndex(slot);
|
||||
}
|
||||
if (component.getDefinition().getType() != InterfaceType.TAB) {
|
||||
SystemLogger.logErr("Set interface type to TAB for component " + component.getId() + ", definition requires updating!");
|
||||
SystemLogger.logErr(this.getClass(), "Set interface type to TAB for component " + component.getId() + ", definition requires updating!");
|
||||
component.getDefinition().setType(InterfaceType.TAB);
|
||||
}
|
||||
component.open(player);
|
||||
@@ -470,7 +470,7 @@ public final class InterfaceManager {
|
||||
*/
|
||||
public void openTab(Component component) {
|
||||
if (component.getDefinition().getTabIndex() < 0) {
|
||||
SystemLogger.logErr("No component definitions found for tab " + component.getId() + "!");
|
||||
SystemLogger.logErr(this.getClass(), "No component definitions found for tab " + component.getId() + "!");
|
||||
return;
|
||||
}
|
||||
openTab(component.getDefinition().getTabIndex(), component);
|
||||
@@ -500,7 +500,7 @@ public final class InterfaceManager {
|
||||
} else {
|
||||
chatbox = component;
|
||||
if (chatbox.getDefinition().getType() != InterfaceType.DIALOGUE && chatbox.getDefinition().getType() != InterfaceType.CHATBOX && chatbox.getDefinition().getType() != InterfaceType.CS_CHATBOX) {
|
||||
SystemLogger.logErr("Set interface type to CHATBOX for component " + component.getId() + ", definition requires updating!");
|
||||
SystemLogger.logErr(this.getClass(), "Set interface type to CHATBOX for component " + component.getId() + ", definition requires updating!");
|
||||
chatbox.getDefinition().setType(InterfaceType.DIALOGUE);
|
||||
}
|
||||
chatbox.open(player);
|
||||
@@ -606,7 +606,7 @@ public final class InterfaceManager {
|
||||
}
|
||||
overlay = component;
|
||||
if (overlay.getDefinition().getType() != InterfaceType.OVERLAY) {
|
||||
SystemLogger.logErr("Set interface type to OVERLAY for component " + component.getId() + ", definition requires updating!");
|
||||
SystemLogger.logErr(this.getClass(), "Set interface type to OVERLAY for component " + component.getId() + ", definition requires updating!");
|
||||
overlay.getDefinition().setType(InterfaceType.OVERLAY);
|
||||
overlay.getDefinition().setWalkable(true);
|
||||
}
|
||||
@@ -623,7 +623,7 @@ public final class InterfaceManager {
|
||||
}
|
||||
wildyOverlay = component;
|
||||
if (wildyOverlay.getDefinition().getType() != InterfaceType.WILDERNESS_OVERLAY) {
|
||||
SystemLogger.logErr("Set interface type to WILDERNESS_OVERLAY for component " + component.getId() + ", definition requires updating!");
|
||||
SystemLogger.logErr(this.getClass(), "Set interface type to WILDERNESS_OVERLAY for component " + component.getId() + ", definition requires updating!");
|
||||
wildyOverlay.getDefinition().setType(InterfaceType.WILDERNESS_OVERLAY);
|
||||
wildyOverlay.getDefinition().setWalkable(true);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public final class PacketDispatch {
|
||||
return;
|
||||
}
|
||||
if (message.length() > 255) {
|
||||
SystemLogger.logErr("Message length out of bounds (" + message + ")!");
|
||||
SystemLogger.logErr(this.getClass(), "Message length out of bounds (" + message + ")!");
|
||||
message = message.substring(0, 255);
|
||||
}
|
||||
PacketRepository.send(GameMessage.class, new GameMessageContext(player, message));
|
||||
|
||||
@@ -100,7 +100,7 @@ public final class QuestRepository {
|
||||
if(oldStage < stage) {
|
||||
quests.put(quest.getIndex(), stage);
|
||||
} else {
|
||||
SystemLogger.logWarn(String.format("Nonmonotonic QuestRepository.setStage call for player \"%s\", quest \"%s\", old stage %d, new stage %d", player.getName(), quest.getName(), oldStage, stage));
|
||||
SystemLogger.logWarn(this.getClass(), String.format("Nonmonotonic QuestRepository.setStage call for player \"%s\", quest \"%s\", old stage %d, new stage %d", player.getName(), quest.getName(), oldStage, stage));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ public final class QuestRepository {
|
||||
public boolean isComplete(String name) {
|
||||
Quest quest = getQuest(name);
|
||||
if (quest == null) {
|
||||
SystemLogger.logErr("Error can't check if quest is complete for " + name);
|
||||
SystemLogger.logErr(this.getClass(), "Error can't check if quest is complete for " + name);
|
||||
return false;
|
||||
}
|
||||
return quest.getStage(player) >= 100;
|
||||
@@ -219,7 +219,7 @@ public final class QuestRepository {
|
||||
public boolean hasStarted(String name) {
|
||||
Quest quest = getQuest(name);
|
||||
if (quest == null) {
|
||||
SystemLogger.logErr("Error can't check if quest is complete for " + name);
|
||||
SystemLogger.logErr(this.getClass(), "Error can't check if quest is complete for " + name);
|
||||
return false;
|
||||
}
|
||||
return quest.getStage(player) > 0;
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ public final class BuildOptionPlugin extends OptionHandler {
|
||||
Hotspot hotspot = player.getHouseManager().getHotspot(object);
|
||||
if (hotspot == null || !isBuildable(player, object, hotspot)) {
|
||||
System.out.println(hotspot == null);
|
||||
SystemLogger.logErr("Construction (building): " + hotspot + " : " + object + " chunkX = " + object.getLocation().getChunkX() + ", chunkY = " + object.getLocation().getChunkY());
|
||||
SystemLogger.logErr(this.getClass(), "Construction (building): " + hotspot + " : " + object + " chunkX = " + object.getLocation().getChunkX() + ", chunkY = " + object.getLocation().getChunkY());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ public final class BuildingUtils {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SystemLogger.logErr("Couldn't find stairs! " + plane);
|
||||
SystemLogger.logErr(BuildingUtils.class, "Couldn't find stairs! " + plane);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -409,7 +409,7 @@ public final class BuildingUtils {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SystemLogger.logErr("Couldn't find stairs! " + plane);
|
||||
SystemLogger.logErr(BuildingUtils.class, "Couldn't find stairs! " + plane);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -632,8 +632,8 @@ public final class BuildingUtils {
|
||||
Direction[] directions = new Direction[4];
|
||||
boolean[] exit = Arrays.copyOf(exits, exits.length); //(0=east, 1=south, 2=west, 3=north)
|
||||
int[] info = getExitRequirements(player, z, roomX, roomY);//(0=west, 1=north, 2=east, 3=south)
|
||||
// SystemLogger.logErr("Available exits - [east=" + exit[0] + ", south=" + exit[1] + ", west=" + exit[2] + ", north=" + exit[3] + "]!");
|
||||
// SystemLogger.logErr("Required exits - [east=" + info[0] + ", south=" + info[1] + ", west=" + info[2] + ", north=" + info[3] + "]!");
|
||||
// SystemLogger.logErr(BuildingUtils.class, "Available exits - [east=" + exit[0] + ", south=" + exit[1] + ", west=" + exit[2] + ", north=" + exit[3] + "]!");
|
||||
// SystemLogger.logErr(BuildingUtils.class, "Required exits - [east=" + info[0] + ", south=" + info[1] + ", west=" + info[2] + ", north=" + info[3] + "]!");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
boolean success = true;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
|
||||
+3
-3
@@ -39,12 +39,12 @@ public final class ConstructionInterface extends ComponentPlugin {
|
||||
Hotspot hotspot = player.getAttribute("con:hotspot");
|
||||
Scenery object = player.getAttribute("con:hsobject");
|
||||
if (hotspot == null || object == null) {
|
||||
SystemLogger.logErr("Failed building decoration " + hotspot + " : " + object);
|
||||
SystemLogger.logErr(this.getClass(), "Failed building decoration " + hotspot + " : " + object);
|
||||
break;
|
||||
}
|
||||
slot = ((slot % 2 != 0) ? 4 : 0) + (slot >> 1);
|
||||
if (slot >= hotspot.getHotspot().getDecorations().length) {
|
||||
SystemLogger.logErr("Failed building decoration " + slot + "/" + hotspot.getHotspot().getDecorations().length);
|
||||
SystemLogger.logErr(this.getClass(), "Failed building decoration " + slot + "/" + hotspot.getHotspot().getDecorations().length);
|
||||
break;
|
||||
}
|
||||
boolean debug = player.isStaff();
|
||||
@@ -105,7 +105,7 @@ public final class ConstructionInterface extends ComponentPlugin {
|
||||
break;
|
||||
case 402:
|
||||
int index = button - 160;
|
||||
SystemLogger.logErr("BuildRoom Interface Index: " + index);
|
||||
SystemLogger.logErr(this.getClass(), "BuildRoom Interface Index: " + index);
|
||||
if (index > -1 && index < RoomProperties.values().length) {
|
||||
player.getDialogueInterpreter().open("con:room", RoomProperties.values()[index]);
|
||||
return true;
|
||||
|
||||
@@ -323,7 +323,7 @@ public final class HouseManager {
|
||||
*/
|
||||
public Location getEnterLocation() {
|
||||
if (houseRegion == null) {
|
||||
SystemLogger.logErr("House wasn't constructed yet!");
|
||||
SystemLogger.logErr(this.getClass(), "House wasn't constructed yet!");
|
||||
return null;
|
||||
}
|
||||
for (int x = 0; x < 8; x++) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user