mirror of
https://github.com/cuberite/cuberite.git
synced 2025-01-08 11:57:39 +08:00
Changed everyting to Unix line endings.
This commit is contained in:
parent
20e7221c7c
commit
53e22b1185
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
|
@ -1,33 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>MCServer</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>MCServer</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
@ -1,4 +1,4 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
||||
org.eclipse.jdt.core.compiler.source=1.5
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
||||
org.eclipse.jdt.core.compiler.source=1.5
|
||||
|
@ -1,27 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.mcserver"
|
||||
android:versionCode="3"
|
||||
android:versionName="r1375" >
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_LOGS"/>
|
||||
|
||||
<uses-sdk android:minSdkVersion="10" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name" >
|
||||
<activity
|
||||
android:name=".MCServerActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.mcserver"
|
||||
android:versionCode="3"
|
||||
android:versionName="r1375" >
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_LOGS"/>
|
||||
|
||||
<uses-sdk android:minSdkVersion="10" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name" >
|
||||
<activity
|
||||
android:name=".MCServerActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -1,2 +1,2 @@
|
||||
Put all pre-packaged plugins in here such as Core.
|
||||
Put all pre-packaged plugins in here such as Core.
|
||||
The user will be able to install each plugin in here separately.
|
@ -1,10 +1,10 @@
|
||||
Put all pre-packaged settings/preferences and license files in here.
|
||||
Such as:
|
||||
|
||||
settings.example.ini
|
||||
groups.example.ini
|
||||
users.example.ini
|
||||
webadmin.example.ini
|
||||
Lua-LICENSE.txt
|
||||
MersenneTwister-LICENSE.txt
|
||||
Put all pre-packaged settings/preferences and license files in here.
|
||||
Such as:
|
||||
|
||||
settings.example.ini
|
||||
groups.example.ini
|
||||
users.example.ini
|
||||
webadmin.example.ini
|
||||
Lua-LICENSE.txt
|
||||
MersenneTwister-LICENSE.txt
|
||||
etc.etc
|
@ -1,39 +1,39 @@
|
||||
/* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*
|
||||
* This class was automatically generated by the
|
||||
* aapt tool from the resource data it found. It
|
||||
* should not be modified by hand.
|
||||
*/
|
||||
|
||||
package com.mcserver;
|
||||
|
||||
public final class R {
|
||||
public static final class attr {
|
||||
}
|
||||
public static final class drawable {
|
||||
public static final int ic_launcher=0x7f020000;
|
||||
}
|
||||
public static final class id {
|
||||
public static final int configure_server=0x7f050003;
|
||||
public static final int ip_address=0x7f050005;
|
||||
public static final int listView1=0x7f050006;
|
||||
public static final int server_status_text=0x7f050004;
|
||||
public static final int start_server=0x7f050002;
|
||||
public static final int stop_server=0x7f050001;
|
||||
public static final int textView2=0x7f050000;
|
||||
}
|
||||
public static final class layout {
|
||||
public static final int list_item=0x7f030000;
|
||||
public static final int main=0x7f030001;
|
||||
}
|
||||
public static final class string {
|
||||
public static final int app_name=0x7f040001;
|
||||
public static final int configure=0x7f040007;
|
||||
public static final int hello=0x7f040000;
|
||||
public static final int mcserver_is_not_running=0x7f040005;
|
||||
public static final int mcserver_is_running=0x7f040004;
|
||||
public static final int start=0x7f040002;
|
||||
public static final int stop=0x7f040003;
|
||||
public static final int your_ip=0x7f040006;
|
||||
}
|
||||
}
|
||||
/* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*
|
||||
* This class was automatically generated by the
|
||||
* aapt tool from the resource data it found. It
|
||||
* should not be modified by hand.
|
||||
*/
|
||||
|
||||
package com.mcserver;
|
||||
|
||||
public final class R {
|
||||
public static final class attr {
|
||||
}
|
||||
public static final class drawable {
|
||||
public static final int ic_launcher=0x7f020000;
|
||||
}
|
||||
public static final class id {
|
||||
public static final int configure_server=0x7f050003;
|
||||
public static final int ip_address=0x7f050005;
|
||||
public static final int listView1=0x7f050006;
|
||||
public static final int server_status_text=0x7f050004;
|
||||
public static final int start_server=0x7f050002;
|
||||
public static final int stop_server=0x7f050001;
|
||||
public static final int textView2=0x7f050000;
|
||||
}
|
||||
public static final class layout {
|
||||
public static final int list_item=0x7f030000;
|
||||
public static final int main=0x7f030001;
|
||||
}
|
||||
public static final class string {
|
||||
public static final int app_name=0x7f040001;
|
||||
public static final int configure=0x7f040007;
|
||||
public static final int hello=0x7f040000;
|
||||
public static final int mcserver_is_not_running=0x7f040005;
|
||||
public static final int mcserver_is_running=0x7f040004;
|
||||
public static final int start=0x7f040002;
|
||||
public static final int stop=0x7f040003;
|
||||
public static final int your_ip=0x7f040006;
|
||||
}
|
||||
}
|
||||
|
@ -1,46 +1,46 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := mcserver
|
||||
|
||||
|
||||
|
||||
LOCAL_SRC_FILES := $(shell find ../CryptoPP ../lua-5.1.4 ../jsoncpp-src-0.5.0 ../zlib-1.2.7 ../source ../squirrel_3_0_1_stable ../tolua++-1.0.93 ../iniFile ../WebServer ../expat '(' -name '*.cpp' -o -name '*.c' ')')
|
||||
LOCAL_SRC_FILES := $(filter-out %SquirrelFunctions.cpp %SquirrelBindings.cpp %cPlugin_Squirrel.cpp %cSquirrelCommandBinder.cpp %minigzip.c %lua.c %tolua.c %toluabind.c %LeakFinder.cpp %StackWalker.cpp %example.c,$(LOCAL_SRC_FILES))
|
||||
LOCAL_SRC_FILES := $(patsubst %.cpp,../%.cpp,$(LOCAL_SRC_FILES))
|
||||
LOCAL_SRC_FILES := $(patsubst %.c,../%.c,$(LOCAL_SRC_FILES))
|
||||
LOCAL_SRC_FILES += app-android.cpp ToJava.cpp
|
||||
|
||||
LOCAL_CFLAGS := -DANDROID_NDK \
|
||||
-O3 \
|
||||
-funroll-loops \
|
||||
-mfloat-abi=softfp -mfpu=neon \
|
||||
-fexceptions \
|
||||
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := cpufeatures
|
||||
|
||||
LOCAL_C_INCLUDES := ../source \
|
||||
../source/md5 \
|
||||
../WebServer \
|
||||
../source/packets \
|
||||
../source/items \
|
||||
../source/blocks \
|
||||
../tolua++-1.0.93/src/lib \
|
||||
../lua-5.1.4/src \
|
||||
../zlib-1.2.7 \
|
||||
../iniFile \
|
||||
../tolua++-1.0.93/include \
|
||||
../jsoncpp-src-0.5.0/include \
|
||||
../jsoncpp-src-0.5.0/src/lib_json \
|
||||
../squirrel_3_0_1_stable/include \
|
||||
../squirrel_3_0_1_stable \
|
||||
../squirrel_3_0_1_stable/sqrat \
|
||||
../expat/ \
|
||||
.. \
|
||||
|
||||
|
||||
LOCAL_LDLIBS := -ldl -llog
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
$(call import-module,cpufeatures)
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := mcserver
|
||||
|
||||
|
||||
|
||||
LOCAL_SRC_FILES := $(shell find ../CryptoPP ../lua-5.1.4 ../jsoncpp-src-0.5.0 ../zlib-1.2.7 ../source ../squirrel_3_0_1_stable ../tolua++-1.0.93 ../iniFile ../WebServer ../expat '(' -name '*.cpp' -o -name '*.c' ')')
|
||||
LOCAL_SRC_FILES := $(filter-out %SquirrelFunctions.cpp %SquirrelBindings.cpp %cPlugin_Squirrel.cpp %cSquirrelCommandBinder.cpp %minigzip.c %lua.c %tolua.c %toluabind.c %LeakFinder.cpp %StackWalker.cpp %example.c,$(LOCAL_SRC_FILES))
|
||||
LOCAL_SRC_FILES := $(patsubst %.cpp,../%.cpp,$(LOCAL_SRC_FILES))
|
||||
LOCAL_SRC_FILES := $(patsubst %.c,../%.c,$(LOCAL_SRC_FILES))
|
||||
LOCAL_SRC_FILES += app-android.cpp ToJava.cpp
|
||||
|
||||
LOCAL_CFLAGS := -DANDROID_NDK \
|
||||
-O3 \
|
||||
-funroll-loops \
|
||||
-mfloat-abi=softfp -mfpu=neon \
|
||||
-fexceptions \
|
||||
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := cpufeatures
|
||||
|
||||
LOCAL_C_INCLUDES := ../source \
|
||||
../source/md5 \
|
||||
../WebServer \
|
||||
../source/packets \
|
||||
../source/items \
|
||||
../source/blocks \
|
||||
../tolua++-1.0.93/src/lib \
|
||||
../lua-5.1.4/src \
|
||||
../zlib-1.2.7 \
|
||||
../iniFile \
|
||||
../tolua++-1.0.93/include \
|
||||
../jsoncpp-src-0.5.0/include \
|
||||
../jsoncpp-src-0.5.0/src/lib_json \
|
||||
../squirrel_3_0_1_stable/include \
|
||||
../squirrel_3_0_1_stable \
|
||||
../squirrel_3_0_1_stable/sqrat \
|
||||
../expat/ \
|
||||
.. \
|
||||
|
||||
|
||||
LOCAL_LDLIBS := -ldl -llog
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
$(call import-module,cpufeatures)
|
||||
|
@ -1,3 +1,3 @@
|
||||
#include "Globals.h"
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
#include "ToJava.h"
|
@ -1,59 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
extern JNIEnv* g_CurrentJNIEnv;
|
||||
extern JavaVM* g_JavaVM;
|
||||
extern jobject g_JavaThread;
|
||||
//extern jobject g_JavaActivity;
|
||||
|
||||
//__android_log_vprint(ANDROID_LOG_ERROR,"MCServer", a_Format, argList);
|
||||
|
||||
static void CallJavaFunction_Void_String( jobject a_Object, const std::string & a_FunctionName, const std::string & a_StringParam )
|
||||
{
|
||||
JNIEnv * oldEnv = g_CurrentJNIEnv;
|
||||
int status = g_JavaVM->AttachCurrentThread(&g_CurrentJNIEnv, NULL);
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "STATUS: %i old: %p new: %p", status, oldEnv, g_CurrentJNIEnv );
|
||||
jstring str = g_CurrentJNIEnv->NewStringUTF( a_StringParam.c_str() );
|
||||
|
||||
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "JNIEnv: %i Object: %i", g_CurrentJNIEnv, a_Object );
|
||||
jclass cls = g_CurrentJNIEnv->GetObjectClass( a_Object );
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "jclass: %i", cls );
|
||||
jmethodID mid = g_CurrentJNIEnv->GetMethodID( cls, a_FunctionName.c_str(), "(Ljava/lang/String;)V"); // void a_FunctionName( String )
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "jmethodID: %i", mid );
|
||||
if (mid != 0)
|
||||
{
|
||||
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "Going to call right NOW! %s", a_FunctionName.c_str() );
|
||||
g_CurrentJNIEnv->CallVoidMethod( a_Object, mid, str );
|
||||
}
|
||||
else
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "It was 0, derp" );
|
||||
}
|
||||
|
||||
if( oldEnv != g_CurrentJNIEnv )
|
||||
{
|
||||
g_JavaVM->DetachCurrentThread();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void CallJavaFunction_Void_Void( jobject a_Object, const std::string & a_FunctionName )
|
||||
{
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "JNIEnv: %i Object: %i", g_CurrentJNIEnv, a_Object );
|
||||
jclass cls = g_CurrentJNIEnv->GetObjectClass( a_Object );
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "jclass: %i", cls );
|
||||
jmethodID mid = g_CurrentJNIEnv->GetMethodID( cls, a_FunctionName.c_str(), "()V"); // void a_FunctionName( String )
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "jmethodID: %i", mid );
|
||||
if (mid != 0)
|
||||
{
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "Going to call right NOW! %s", a_FunctionName.c_str() );
|
||||
g_CurrentJNIEnv->CallVoidMethod( a_Object, mid );
|
||||
}
|
||||
else
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "It was 0, derp" );
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
extern JNIEnv* g_CurrentJNIEnv;
|
||||
extern JavaVM* g_JavaVM;
|
||||
extern jobject g_JavaThread;
|
||||
//extern jobject g_JavaActivity;
|
||||
|
||||
//__android_log_vprint(ANDROID_LOG_ERROR,"MCServer", a_Format, argList);
|
||||
|
||||
static void CallJavaFunction_Void_String( jobject a_Object, const std::string & a_FunctionName, const std::string & a_StringParam )
|
||||
{
|
||||
JNIEnv * oldEnv = g_CurrentJNIEnv;
|
||||
int status = g_JavaVM->AttachCurrentThread(&g_CurrentJNIEnv, NULL);
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "STATUS: %i old: %p new: %p", status, oldEnv, g_CurrentJNIEnv );
|
||||
jstring str = g_CurrentJNIEnv->NewStringUTF( a_StringParam.c_str() );
|
||||
|
||||
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "JNIEnv: %i Object: %i", g_CurrentJNIEnv, a_Object );
|
||||
jclass cls = g_CurrentJNIEnv->GetObjectClass( a_Object );
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "jclass: %i", cls );
|
||||
jmethodID mid = g_CurrentJNIEnv->GetMethodID( cls, a_FunctionName.c_str(), "(Ljava/lang/String;)V"); // void a_FunctionName( String )
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "jmethodID: %i", mid );
|
||||
if (mid != 0)
|
||||
{
|
||||
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "Going to call right NOW! %s", a_FunctionName.c_str() );
|
||||
g_CurrentJNIEnv->CallVoidMethod( a_Object, mid, str );
|
||||
}
|
||||
else
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "It was 0, derp" );
|
||||
}
|
||||
|
||||
if( oldEnv != g_CurrentJNIEnv )
|
||||
{
|
||||
g_JavaVM->DetachCurrentThread();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void CallJavaFunction_Void_Void( jobject a_Object, const std::string & a_FunctionName )
|
||||
{
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "JNIEnv: %i Object: %i", g_CurrentJNIEnv, a_Object );
|
||||
jclass cls = g_CurrentJNIEnv->GetObjectClass( a_Object );
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "jclass: %i", cls );
|
||||
jmethodID mid = g_CurrentJNIEnv->GetMethodID( cls, a_FunctionName.c_str(), "()V"); // void a_FunctionName( String )
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "jmethodID: %i", mid );
|
||||
if (mid != 0)
|
||||
{
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "Going to call right NOW! %s", a_FunctionName.c_str() );
|
||||
g_CurrentJNIEnv->CallVoidMethod( a_Object, mid );
|
||||
}
|
||||
else
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "It was 0, derp" );
|
||||
}
|
||||
}
|
@ -1,130 +1,130 @@
|
||||
#include "Globals.h"
|
||||
|
||||
#include <jni.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "OSSupport/CriticalSection.h"
|
||||
#include "OSSupport/MakeDir.h"
|
||||
#include "ToJava.h"
|
||||
|
||||
#include "Root.h"
|
||||
#include "WebAdmin.h"
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#ifdef _WIN32 // For IntelliSense parsing
|
||||
typedef void jobject;
|
||||
typedef int jint;
|
||||
typedef bool jboolean;
|
||||
typedef void JavaVM;
|
||||
typedef void JNIEnv;
|
||||
#endif
|
||||
|
||||
cCriticalSection g_CriticalSection;
|
||||
|
||||
JNIEnv* g_CurrentJNIEnv = 0;
|
||||
jobject g_JavaThread = 0;
|
||||
JavaVM* g_JavaVM = 0;
|
||||
//jobject g_JavaActivity = 0;
|
||||
|
||||
cRoot * pRoot = NULL;
|
||||
|
||||
|
||||
class cMainThread :
|
||||
public cIsThread
|
||||
{
|
||||
public:
|
||||
cMainThread() :
|
||||
cIsThread("cMainThread")
|
||||
{
|
||||
//Start();
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "%s", "cMainThread");
|
||||
}
|
||||
|
||||
void Stop(void)
|
||||
{
|
||||
m_ShouldTerminate = true;
|
||||
Wait();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void Execute(void) override
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "%s", "Execute");
|
||||
pRoot = new cRoot();
|
||||
pRoot->Start();
|
||||
delete pRoot;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
cMainThread * pMainThread = NULL;
|
||||
|
||||
jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||
{
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "%s", "JNI_OnLoad JNI_OnLoad JNI_OnLoad JNI_OnLoad");
|
||||
g_JavaVM = vm;
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
/* Called when program/activity is created */
|
||||
extern "C" void Java_com_mcserver_MCServerActivity_NativeOnCreate( JNIEnv* env, jobject thiz )
|
||||
{
|
||||
g_CriticalSection.Lock();
|
||||
g_CurrentJNIEnv = env;
|
||||
g_JavaThread = thiz;
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "%s", "Logging from C++!");
|
||||
g_CriticalSection.Unlock();
|
||||
|
||||
mkdir("/sdcard/mcserver", S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
|
||||
pRoot = new cRoot();
|
||||
pRoot->Start();
|
||||
delete pRoot; pRoot = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C" void Java_com_mcserver_MCServerActivity_NativeCleanUp( JNIEnv* env, jobject thiz )
|
||||
{
|
||||
g_CriticalSection.Lock();
|
||||
g_CurrentJNIEnv = env;
|
||||
g_JavaThread = thiz;
|
||||
g_CriticalSection.Unlock();
|
||||
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "pRoot: %p", pRoot);
|
||||
if( pRoot != NULL )
|
||||
{
|
||||
pRoot->ExecuteConsoleCommand("stop");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C" jboolean Java_com_mcserver_MCServerActivity_NativeIsServerRunning( JNIEnv* env, jobject thiz )
|
||||
{
|
||||
return pRoot != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C" jint Java_com_mcserver_MCServerActivity_NativeGetWebAdminPort( JNIEnv* env, jobject thiz )
|
||||
{
|
||||
if( pRoot != NULL && pRoot->GetWebAdmin() != NULL )
|
||||
{
|
||||
return pRoot->GetWebAdmin()->GetPort();
|
||||
}
|
||||
return 0;
|
||||
#include "Globals.h"
|
||||
|
||||
#include <jni.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "OSSupport/CriticalSection.h"
|
||||
#include "OSSupport/MakeDir.h"
|
||||
#include "ToJava.h"
|
||||
|
||||
#include "Root.h"
|
||||
#include "WebAdmin.h"
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#ifdef _WIN32 // For IntelliSense parsing
|
||||
typedef void jobject;
|
||||
typedef int jint;
|
||||
typedef bool jboolean;
|
||||
typedef void JavaVM;
|
||||
typedef void JNIEnv;
|
||||
#endif
|
||||
|
||||
cCriticalSection g_CriticalSection;
|
||||
|
||||
JNIEnv* g_CurrentJNIEnv = 0;
|
||||
jobject g_JavaThread = 0;
|
||||
JavaVM* g_JavaVM = 0;
|
||||
//jobject g_JavaActivity = 0;
|
||||
|
||||
cRoot * pRoot = NULL;
|
||||
|
||||
|
||||
class cMainThread :
|
||||
public cIsThread
|
||||
{
|
||||
public:
|
||||
cMainThread() :
|
||||
cIsThread("cMainThread")
|
||||
{
|
||||
//Start();
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "%s", "cMainThread");
|
||||
}
|
||||
|
||||
void Stop(void)
|
||||
{
|
||||
m_ShouldTerminate = true;
|
||||
Wait();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void Execute(void) override
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "%s", "Execute");
|
||||
pRoot = new cRoot();
|
||||
pRoot->Start();
|
||||
delete pRoot;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
cMainThread * pMainThread = NULL;
|
||||
|
||||
jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||
{
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "%s", "JNI_OnLoad JNI_OnLoad JNI_OnLoad JNI_OnLoad");
|
||||
g_JavaVM = vm;
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
/* Called when program/activity is created */
|
||||
extern "C" void Java_com_mcserver_MCServerActivity_NativeOnCreate( JNIEnv* env, jobject thiz )
|
||||
{
|
||||
g_CriticalSection.Lock();
|
||||
g_CurrentJNIEnv = env;
|
||||
g_JavaThread = thiz;
|
||||
//__android_log_print(ANDROID_LOG_ERROR,"MCServer", "%s", "Logging from C++!");
|
||||
g_CriticalSection.Unlock();
|
||||
|
||||
mkdir("/sdcard/mcserver", S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
|
||||
pRoot = new cRoot();
|
||||
pRoot->Start();
|
||||
delete pRoot; pRoot = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C" void Java_com_mcserver_MCServerActivity_NativeCleanUp( JNIEnv* env, jobject thiz )
|
||||
{
|
||||
g_CriticalSection.Lock();
|
||||
g_CurrentJNIEnv = env;
|
||||
g_JavaThread = thiz;
|
||||
g_CriticalSection.Unlock();
|
||||
|
||||
__android_log_print(ANDROID_LOG_ERROR,"MCServer", "pRoot: %p", pRoot);
|
||||
if( pRoot != NULL )
|
||||
{
|
||||
pRoot->ExecuteConsoleCommand("stop");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C" jboolean Java_com_mcserver_MCServerActivity_NativeIsServerRunning( JNIEnv* env, jobject thiz )
|
||||
{
|
||||
return pRoot != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C" jint Java_com_mcserver_MCServerActivity_NativeGetWebAdminPort( JNIEnv* env, jobject thiz )
|
||||
{
|
||||
if( pRoot != NULL && pRoot->GetWebAdmin() != NULL )
|
||||
{
|
||||
return pRoot->GetWebAdmin()->GetPort();
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,61 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical" >
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
<Button
|
||||
android:id="@+id/stop_server"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:enabled="true"
|
||||
android:text="@string/stop" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/start_server"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/start" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/stop_server"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:enabled="true"
|
||||
android:text="@string/stop" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/start_server"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/start" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/configure_server"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/configure" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/server_status_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/mcserver_is_not_running"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ip_address"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/your_ip" />
|
||||
<ListView
|
||||
android:id="@+id/listView1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
</ListView>
|
||||
|
||||
<Button
|
||||
android:id="@+id/configure_server"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/configure" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/server_status_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/mcserver_is_not_running"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ip_address"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/your_ip" />
|
||||
<ListView
|
||||
android:id="@+id/listView1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
</ListView>
|
||||
|
||||
</LinearLayout>
|
@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="hello">Hello World, MCServerActivity!</string>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="hello">Hello World, MCServerActivity!</string>
|
||||
<string name="app_name">MCServer</string>
|
||||
<string name="start">Start</string>
|
||||
<string name="stop">Stop</string>
|
||||
<string name="mcserver_is_running">MCServer is running</string>
|
||||
<string name="mcserver_is_not_running">MCServer is not running</string>
|
||||
<string name="your_ip">Your IP …</string>
|
||||
<string name="configure">Configure</string>
|
||||
|
||||
<string name="your_ip">Your IP …</string>
|
||||
<string name="configure">Configure</string>
|
||||
|
||||
</resources>
|
@ -1,432 +1,432 @@
|
||||
package com.mcserver;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
public class MCServerInstaller {
|
||||
private MCServerActivity mContext;
|
||||
final private String BaseDirectory = "basedir";
|
||||
final private String PluginDirectory = "Plugins";
|
||||
|
||||
final public String SHARED_PREFS_NAME = "MCSERVER_PREFS";
|
||||
final public String PREF_IS_INSTALLED = "IS_INSTALLED";
|
||||
final public String PREF_LAST_VERSION = "LAST_VERSION";
|
||||
private SharedPreferences mSettings = null;
|
||||
|
||||
int thisVersion;
|
||||
|
||||
MCServerInstaller( MCServerActivity activity )
|
||||
{
|
||||
mContext = activity;
|
||||
|
||||
mSettings = mContext.getSharedPreferences( SHARED_PREFS_NAME, 0);
|
||||
|
||||
try {
|
||||
this.thisVersion = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode;
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.e("MCServer", "Could not read version code from manifest!");
|
||||
e.printStackTrace();
|
||||
this.thisVersion = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean IsInstalled()
|
||||
{
|
||||
return mSettings.getBoolean(PREF_IS_INSTALLED, false);
|
||||
}
|
||||
|
||||
|
||||
public boolean NeedsUpdate()
|
||||
{
|
||||
Log.i("MCServer", "thisVersion: " + this.thisVersion + " pref: " + mSettings.getInt(PREF_LAST_VERSION, 0));
|
||||
return mSettings.getInt(PREF_LAST_VERSION, 0) != this.thisVersion;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<String> FindFoldersInPath(String path)
|
||||
{
|
||||
ArrayList<String> allFolders = new ArrayList<String>();
|
||||
AssetManager am = mContext.getAssets();
|
||||
try {
|
||||
String[] allPlugins = am.list(path);
|
||||
for(String pluginName : allPlugins)
|
||||
{
|
||||
InputStream istr = null;
|
||||
try
|
||||
{
|
||||
istr = am.open(path + "/" + pluginName);
|
||||
} catch( java.io.FileNotFoundException e ) {
|
||||
// It seems to be a folder :D
|
||||
allFolders.add(pluginName);
|
||||
continue;
|
||||
}
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return allFolders;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void ExpandAssets( String path )
|
||||
{
|
||||
AssetManager am = mContext.getAssets();
|
||||
try {
|
||||
String[] getAssets = am.list(path);
|
||||
for(String assetName : getAssets)
|
||||
{
|
||||
//Log.e("MCServer", path + "/" + imgName);
|
||||
|
||||
InputStream istr = null;
|
||||
try
|
||||
{
|
||||
istr = am.open(path + "/" + assetName);
|
||||
} catch( java.io.FileNotFoundException e ) {
|
||||
//Log.e("MCServer", "Could not open" + path + "/" + imgName );
|
||||
ExpandAssets(path + "/" + assetName);
|
||||
continue;
|
||||
}
|
||||
|
||||
String outPath = Environment.getExternalStorageDirectory().getPath() + "/mcserver/" + path + "/" + assetName;
|
||||
//Log.e("MCServer", "outPath: " + outPath );
|
||||
File f = new File( outPath );
|
||||
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
OutputStream ostr = new FileOutputStream(f);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = istr.read(buffer))>0)
|
||||
{
|
||||
ostr.write(buffer, 0, length);
|
||||
}
|
||||
ostr.flush();
|
||||
ostr.close();
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ShowFirstRunDialog()
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
||||
//builder.setTitle("blaa");
|
||||
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setMessage("It seems this is the first time you are running MCServer on your Android device or it has been updated! This app comes with a couple of pre-packaged plugins, please take a moment to select the plugins you would like to install.");
|
||||
builder.setCancelable(false);
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
|
||||
dialog.setOnDismissListener( new DialogInterface.OnDismissListener(){
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
ShowPluginInstallDialog(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void ShowPluginInstallDialog(boolean bCancelable)
|
||||
{
|
||||
final ArrayList<String> allPlugins = FindFoldersInPath( BaseDirectory + "/" + PluginDirectory );
|
||||
final CharSequence[] items = allPlugins.toArray(new CharSequence[allPlugins.size()]);
|
||||
final boolean[] selected = new boolean[items.length];
|
||||
for( int i = 0; i < items.length; ++i )
|
||||
{
|
||||
if( items[i].toString().contains("Core") )
|
||||
{ // Select the core plugin by default
|
||||
selected[i] = true;
|
||||
items[i] = items[i] + " (Recommended)";
|
||||
}
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
||||
builder.setTitle("Plugins to install");
|
||||
builder.setCancelable(bCancelable);
|
||||
builder.setMultiChoiceItems(items, selected, new DialogInterface.OnMultiChoiceClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
|
||||
selected[which] = isChecked;
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton("Install", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
ArrayList<String> toInstall = new ArrayList<String>();
|
||||
for( int i = 0; i < selected.length; ++i )
|
||||
{
|
||||
if( selected[i] )
|
||||
{
|
||||
toInstall.add(allPlugins.get(i));
|
||||
}
|
||||
}
|
||||
InstallPlugins(toInstall);
|
||||
}
|
||||
});
|
||||
|
||||
AlertDialog dialog2 = builder.create();
|
||||
dialog2.show();
|
||||
}
|
||||
|
||||
|
||||
void InstallPlugins( final ArrayList<String> plugins )
|
||||
{
|
||||
new AsyncTask<Void, Integer, Boolean>()
|
||||
{
|
||||
ProgressDialog progressDialog;
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
{
|
||||
/*
|
||||
* This is executed on UI thread before doInBackground(). It is
|
||||
* the perfect place to show the progress dialog.
|
||||
*/
|
||||
progressDialog = ProgressDialog.show(mContext, "", "Installing...");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... params)
|
||||
{
|
||||
if (params == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
/*
|
||||
* This is run on a background thread, so we can sleep here
|
||||
* or do whatever we want without blocking UI thread. A more
|
||||
* advanced use would download chunks of fixed size and call
|
||||
* publishProgress();
|
||||
*/
|
||||
for( int i = 0; i < plugins.size(); ++i )
|
||||
{
|
||||
this.publishProgress((int)(i / (float)plugins.size() * 100), i);
|
||||
InstallSinglePlugin(PluginDirectory + "/" + plugins.get(i));
|
||||
}
|
||||
|
||||
this.publishProgress( 100, -1 );
|
||||
InstallExampleSettings();
|
||||
|
||||
this.publishProgress( 100, -2 );
|
||||
InstallWebAdmin();
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.e("tag", e.getMessage());
|
||||
/*
|
||||
* The task failed
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The task succeeded
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void onProgressUpdate(Integer... progress)
|
||||
{
|
||||
progressDialog.setProgress(progress[0]);
|
||||
if( progress[1] > -1 )
|
||||
{
|
||||
progressDialog.setMessage("Installing " + plugins.get(progress[1]) + "..." );
|
||||
}
|
||||
else if( progress[1] == -1 )
|
||||
{
|
||||
progressDialog.setMessage("Installing default settings...");
|
||||
}
|
||||
else if( progress[1] == -2 )
|
||||
{
|
||||
progressDialog.setMessage("Installing WebAdmin...");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
/*
|
||||
* Update here your view objects with content from download. It
|
||||
* is save to dismiss dialogs, update views, etc., since we are
|
||||
* working on UI thread.
|
||||
*/
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(mContext);
|
||||
b.setTitle(android.R.string.dialog_alert_title);
|
||||
if (result)
|
||||
{
|
||||
b.setMessage("Install succeeded");
|
||||
|
||||
SharedPreferences.Editor editor = mSettings.edit();
|
||||
editor.putBoolean(PREF_IS_INSTALLED, true);
|
||||
editor.putInt(PREF_LAST_VERSION, thisVersion);
|
||||
editor.commit();
|
||||
}
|
||||
else
|
||||
{
|
||||
b.setMessage("Install failed");
|
||||
}
|
||||
b.setPositiveButton(android.R.string.ok,
|
||||
new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
b.create().show();
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
|
||||
void InstallExampleSettings()
|
||||
{
|
||||
AssetManager am = mContext.getAssets();
|
||||
try {
|
||||
String[] allFiles = am.list(BaseDirectory);
|
||||
for(String fileName : allFiles)
|
||||
{
|
||||
InputStream istr = null;
|
||||
try
|
||||
{
|
||||
istr = am.open(BaseDirectory + "/" + fileName);
|
||||
} catch( java.io.FileNotFoundException e ) {
|
||||
// Must be a folder :D
|
||||
continue;
|
||||
}
|
||||
|
||||
String outPath = Environment.getExternalStorageDirectory().getPath() + "/mcserver/" + fileName;
|
||||
Log.i("MCServer", "outPath: " + outPath );
|
||||
File f = new File( outPath );
|
||||
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
OutputStream ostr = new FileOutputStream(f);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = istr.read(buffer))>0)
|
||||
{
|
||||
ostr.write(buffer, 0, length);
|
||||
}
|
||||
ostr.flush();
|
||||
ostr.close();
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InstallWebAdmin()
|
||||
{
|
||||
AssetManager am = mContext.getAssets();
|
||||
try {
|
||||
String[] allFiles = am.list(BaseDirectory + "/webadmin");
|
||||
for(String fileName : allFiles)
|
||||
{
|
||||
InputStream istr = null;
|
||||
try
|
||||
{
|
||||
istr = am.open(BaseDirectory + "/webadmin/" + fileName);
|
||||
} catch( java.io.FileNotFoundException e ) {
|
||||
// Must be a folder :D
|
||||
continue;
|
||||
}
|
||||
|
||||
String outPath = Environment.getExternalStorageDirectory().getPath() + "/mcserver/webadmin/" + fileName;
|
||||
Log.i("MCServer", "outPath: " + outPath );
|
||||
File f = new File( outPath );
|
||||
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
OutputStream ostr = new FileOutputStream(f);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = istr.read(buffer))>0)
|
||||
{
|
||||
ostr.write(buffer, 0, length);
|
||||
}
|
||||
ostr.flush();
|
||||
ostr.close();
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InstallSinglePlugin( String path )
|
||||
{
|
||||
AssetManager am = mContext.getAssets();
|
||||
try {
|
||||
String[] getImages = am.list(BaseDirectory + "/" + path);
|
||||
for(String imgName : getImages)
|
||||
{
|
||||
Log.i("MCServer", path + "/" + imgName);
|
||||
|
||||
InputStream istr = null;
|
||||
try
|
||||
{
|
||||
istr = am.open(BaseDirectory + "/" + path + "/" + imgName);
|
||||
} catch( java.io.FileNotFoundException e ) {
|
||||
Log.i("MCServer", "Could not open" + path + "/" + imgName );
|
||||
InstallSinglePlugin(path + "/" + imgName);
|
||||
continue;
|
||||
}
|
||||
|
||||
String outPath = Environment.getExternalStorageDirectory().getPath() + "/mcserver/" + path + "/" + imgName;
|
||||
Log.i("MCServer", "outPath: " + outPath );
|
||||
File f = new File( outPath );
|
||||
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
OutputStream ostr = new FileOutputStream(f);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = istr.read(buffer))>0)
|
||||
{
|
||||
ostr.write(buffer, 0, length);
|
||||
}
|
||||
ostr.flush();
|
||||
ostr.close();
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.mcserver;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
public class MCServerInstaller {
|
||||
private MCServerActivity mContext;
|
||||
final private String BaseDirectory = "basedir";
|
||||
final private String PluginDirectory = "Plugins";
|
||||
|
||||
final public String SHARED_PREFS_NAME = "MCSERVER_PREFS";
|
||||
final public String PREF_IS_INSTALLED = "IS_INSTALLED";
|
||||
final public String PREF_LAST_VERSION = "LAST_VERSION";
|
||||
private SharedPreferences mSettings = null;
|
||||
|
||||
int thisVersion;
|
||||
|
||||
MCServerInstaller( MCServerActivity activity )
|
||||
{
|
||||
mContext = activity;
|
||||
|
||||
mSettings = mContext.getSharedPreferences( SHARED_PREFS_NAME, 0);
|
||||
|
||||
try {
|
||||
this.thisVersion = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode;
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.e("MCServer", "Could not read version code from manifest!");
|
||||
e.printStackTrace();
|
||||
this.thisVersion = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean IsInstalled()
|
||||
{
|
||||
return mSettings.getBoolean(PREF_IS_INSTALLED, false);
|
||||
}
|
||||
|
||||
|
||||
public boolean NeedsUpdate()
|
||||
{
|
||||
Log.i("MCServer", "thisVersion: " + this.thisVersion + " pref: " + mSettings.getInt(PREF_LAST_VERSION, 0));
|
||||
return mSettings.getInt(PREF_LAST_VERSION, 0) != this.thisVersion;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<String> FindFoldersInPath(String path)
|
||||
{
|
||||
ArrayList<String> allFolders = new ArrayList<String>();
|
||||
AssetManager am = mContext.getAssets();
|
||||
try {
|
||||
String[] allPlugins = am.list(path);
|
||||
for(String pluginName : allPlugins)
|
||||
{
|
||||
InputStream istr = null;
|
||||
try
|
||||
{
|
||||
istr = am.open(path + "/" + pluginName);
|
||||
} catch( java.io.FileNotFoundException e ) {
|
||||
// It seems to be a folder :D
|
||||
allFolders.add(pluginName);
|
||||
continue;
|
||||
}
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return allFolders;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void ExpandAssets( String path )
|
||||
{
|
||||
AssetManager am = mContext.getAssets();
|
||||
try {
|
||||
String[] getAssets = am.list(path);
|
||||
for(String assetName : getAssets)
|
||||
{
|
||||
//Log.e("MCServer", path + "/" + imgName);
|
||||
|
||||
InputStream istr = null;
|
||||
try
|
||||
{
|
||||
istr = am.open(path + "/" + assetName);
|
||||
} catch( java.io.FileNotFoundException e ) {
|
||||
//Log.e("MCServer", "Could not open" + path + "/" + imgName );
|
||||
ExpandAssets(path + "/" + assetName);
|
||||
continue;
|
||||
}
|
||||
|
||||
String outPath = Environment.getExternalStorageDirectory().getPath() + "/mcserver/" + path + "/" + assetName;
|
||||
//Log.e("MCServer", "outPath: " + outPath );
|
||||
File f = new File( outPath );
|
||||
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
OutputStream ostr = new FileOutputStream(f);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = istr.read(buffer))>0)
|
||||
{
|
||||
ostr.write(buffer, 0, length);
|
||||
}
|
||||
ostr.flush();
|
||||
ostr.close();
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ShowFirstRunDialog()
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
||||
//builder.setTitle("blaa");
|
||||
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setMessage("It seems this is the first time you are running MCServer on your Android device or it has been updated! This app comes with a couple of pre-packaged plugins, please take a moment to select the plugins you would like to install.");
|
||||
builder.setCancelable(false);
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
|
||||
dialog.setOnDismissListener( new DialogInterface.OnDismissListener(){
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
ShowPluginInstallDialog(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void ShowPluginInstallDialog(boolean bCancelable)
|
||||
{
|
||||
final ArrayList<String> allPlugins = FindFoldersInPath( BaseDirectory + "/" + PluginDirectory );
|
||||
final CharSequence[] items = allPlugins.toArray(new CharSequence[allPlugins.size()]);
|
||||
final boolean[] selected = new boolean[items.length];
|
||||
for( int i = 0; i < items.length; ++i )
|
||||
{
|
||||
if( items[i].toString().contains("Core") )
|
||||
{ // Select the core plugin by default
|
||||
selected[i] = true;
|
||||
items[i] = items[i] + " (Recommended)";
|
||||
}
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
||||
builder.setTitle("Plugins to install");
|
||||
builder.setCancelable(bCancelable);
|
||||
builder.setMultiChoiceItems(items, selected, new DialogInterface.OnMultiChoiceClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
|
||||
selected[which] = isChecked;
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton("Install", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
ArrayList<String> toInstall = new ArrayList<String>();
|
||||
for( int i = 0; i < selected.length; ++i )
|
||||
{
|
||||
if( selected[i] )
|
||||
{
|
||||
toInstall.add(allPlugins.get(i));
|
||||
}
|
||||
}
|
||||
InstallPlugins(toInstall);
|
||||
}
|
||||
});
|
||||
|
||||
AlertDialog dialog2 = builder.create();
|
||||
dialog2.show();
|
||||
}
|
||||
|
||||
|
||||
void InstallPlugins( final ArrayList<String> plugins )
|
||||
{
|
||||
new AsyncTask<Void, Integer, Boolean>()
|
||||
{
|
||||
ProgressDialog progressDialog;
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
{
|
||||
/*
|
||||
* This is executed on UI thread before doInBackground(). It is
|
||||
* the perfect place to show the progress dialog.
|
||||
*/
|
||||
progressDialog = ProgressDialog.show(mContext, "", "Installing...");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... params)
|
||||
{
|
||||
if (params == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
/*
|
||||
* This is run on a background thread, so we can sleep here
|
||||
* or do whatever we want without blocking UI thread. A more
|
||||
* advanced use would download chunks of fixed size and call
|
||||
* publishProgress();
|
||||
*/
|
||||
for( int i = 0; i < plugins.size(); ++i )
|
||||
{
|
||||
this.publishProgress((int)(i / (float)plugins.size() * 100), i);
|
||||
InstallSinglePlugin(PluginDirectory + "/" + plugins.get(i));
|
||||
}
|
||||
|
||||
this.publishProgress( 100, -1 );
|
||||
InstallExampleSettings();
|
||||
|
||||
this.publishProgress( 100, -2 );
|
||||
InstallWebAdmin();
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.e("tag", e.getMessage());
|
||||
/*
|
||||
* The task failed
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The task succeeded
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void onProgressUpdate(Integer... progress)
|
||||
{
|
||||
progressDialog.setProgress(progress[0]);
|
||||
if( progress[1] > -1 )
|
||||
{
|
||||
progressDialog.setMessage("Installing " + plugins.get(progress[1]) + "..." );
|
||||
}
|
||||
else if( progress[1] == -1 )
|
||||
{
|
||||
progressDialog.setMessage("Installing default settings...");
|
||||
}
|
||||
else if( progress[1] == -2 )
|
||||
{
|
||||
progressDialog.setMessage("Installing WebAdmin...");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
/*
|
||||
* Update here your view objects with content from download. It
|
||||
* is save to dismiss dialogs, update views, etc., since we are
|
||||
* working on UI thread.
|
||||
*/
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(mContext);
|
||||
b.setTitle(android.R.string.dialog_alert_title);
|
||||
if (result)
|
||||
{
|
||||
b.setMessage("Install succeeded");
|
||||
|
||||
SharedPreferences.Editor editor = mSettings.edit();
|
||||
editor.putBoolean(PREF_IS_INSTALLED, true);
|
||||
editor.putInt(PREF_LAST_VERSION, thisVersion);
|
||||
editor.commit();
|
||||
}
|
||||
else
|
||||
{
|
||||
b.setMessage("Install failed");
|
||||
}
|
||||
b.setPositiveButton(android.R.string.ok,
|
||||
new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
b.create().show();
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
|
||||
void InstallExampleSettings()
|
||||
{
|
||||
AssetManager am = mContext.getAssets();
|
||||
try {
|
||||
String[] allFiles = am.list(BaseDirectory);
|
||||
for(String fileName : allFiles)
|
||||
{
|
||||
InputStream istr = null;
|
||||
try
|
||||
{
|
||||
istr = am.open(BaseDirectory + "/" + fileName);
|
||||
} catch( java.io.FileNotFoundException e ) {
|
||||
// Must be a folder :D
|
||||
continue;
|
||||
}
|
||||
|
||||
String outPath = Environment.getExternalStorageDirectory().getPath() + "/mcserver/" + fileName;
|
||||
Log.i("MCServer", "outPath: " + outPath );
|
||||
File f = new File( outPath );
|
||||
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
OutputStream ostr = new FileOutputStream(f);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = istr.read(buffer))>0)
|
||||
{
|
||||
ostr.write(buffer, 0, length);
|
||||
}
|
||||
ostr.flush();
|
||||
ostr.close();
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InstallWebAdmin()
|
||||
{
|
||||
AssetManager am = mContext.getAssets();
|
||||
try {
|
||||
String[] allFiles = am.list(BaseDirectory + "/webadmin");
|
||||
for(String fileName : allFiles)
|
||||
{
|
||||
InputStream istr = null;
|
||||
try
|
||||
{
|
||||
istr = am.open(BaseDirectory + "/webadmin/" + fileName);
|
||||
} catch( java.io.FileNotFoundException e ) {
|
||||
// Must be a folder :D
|
||||
continue;
|
||||
}
|
||||
|
||||
String outPath = Environment.getExternalStorageDirectory().getPath() + "/mcserver/webadmin/" + fileName;
|
||||
Log.i("MCServer", "outPath: " + outPath );
|
||||
File f = new File( outPath );
|
||||
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
OutputStream ostr = new FileOutputStream(f);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = istr.read(buffer))>0)
|
||||
{
|
||||
ostr.write(buffer, 0, length);
|
||||
}
|
||||
ostr.flush();
|
||||
ostr.close();
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InstallSinglePlugin( String path )
|
||||
{
|
||||
AssetManager am = mContext.getAssets();
|
||||
try {
|
||||
String[] getImages = am.list(BaseDirectory + "/" + path);
|
||||
for(String imgName : getImages)
|
||||
{
|
||||
Log.i("MCServer", path + "/" + imgName);
|
||||
|
||||
InputStream istr = null;
|
||||
try
|
||||
{
|
||||
istr = am.open(BaseDirectory + "/" + path + "/" + imgName);
|
||||
} catch( java.io.FileNotFoundException e ) {
|
||||
Log.i("MCServer", "Could not open" + path + "/" + imgName );
|
||||
InstallSinglePlugin(path + "/" + imgName);
|
||||
continue;
|
||||
}
|
||||
|
||||
String outPath = Environment.getExternalStorageDirectory().getPath() + "/mcserver/" + path + "/" + imgName;
|
||||
Log.i("MCServer", "outPath: " + outPath );
|
||||
File f = new File( outPath );
|
||||
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
OutputStream ostr = new FileOutputStream(f);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = istr.read(buffer))>0)
|
||||
{
|
||||
ostr.write(buffer, 0, length);
|
||||
}
|
||||
ostr.flush();
|
||||
ostr.close();
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,180 +1,180 @@
|
||||
// authenc.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#ifndef CRYPTOPP_IMPORTS
|
||||
|
||||
#include "authenc.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::AuthenticateData(const byte *input, size_t len)
|
||||
{
|
||||
unsigned int blockSize = AuthenticationBlockSize();
|
||||
unsigned int &num = m_bufferedDataLength;
|
||||
byte* data = m_buffer.begin();
|
||||
|
||||
if (num != 0) // process left over data
|
||||
{
|
||||
if (num+len >= blockSize)
|
||||
{
|
||||
memcpy(data+num, input, blockSize-num);
|
||||
AuthenticateBlocks(data, blockSize);
|
||||
input += (blockSize-num);
|
||||
len -= (blockSize-num);
|
||||
num = 0;
|
||||
// drop through and do the rest
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(data+num, input, len);
|
||||
num += (unsigned int)len;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// now process the input data in blocks of blockSize bytes and save the leftovers to m_data
|
||||
if (len >= blockSize)
|
||||
{
|
||||
size_t leftOver = AuthenticateBlocks(input, len);
|
||||
input += (len - leftOver);
|
||||
len = leftOver;
|
||||
}
|
||||
|
||||
memcpy(data, input, len);
|
||||
num = (unsigned int)len;
|
||||
}
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::SetKey(const byte *userKey, size_t keylength, const NameValuePairs ¶ms)
|
||||
{
|
||||
m_bufferedDataLength = 0;
|
||||
m_state = State_Start;
|
||||
|
||||
SetKeyWithoutResync(userKey, keylength, params);
|
||||
m_state = State_KeySet;
|
||||
|
||||
size_t length;
|
||||
const byte *iv = GetIVAndThrowIfInvalid(params, length);
|
||||
if (iv)
|
||||
Resynchronize(iv, (int)length);
|
||||
}
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::Resynchronize(const byte *iv, int length)
|
||||
{
|
||||
if (m_state < State_KeySet)
|
||||
throw BadState(AlgorithmName(), "Resynchronize", "key is set");
|
||||
|
||||
m_bufferedDataLength = 0;
|
||||
m_totalHeaderLength = m_totalMessageLength = m_totalFooterLength = 0;
|
||||
m_state = State_KeySet;
|
||||
|
||||
Resync(iv, this->ThrowIfInvalidIVLength(length));
|
||||
m_state = State_IVSet;
|
||||
}
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::Update(const byte *input, size_t length)
|
||||
{
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
switch (m_state)
|
||||
{
|
||||
case State_Start:
|
||||
case State_KeySet:
|
||||
throw BadState(AlgorithmName(), "Update", "setting key and IV");
|
||||
case State_IVSet:
|
||||
AuthenticateData(input, length);
|
||||
m_totalHeaderLength += length;
|
||||
break;
|
||||
case State_AuthUntransformed:
|
||||
case State_AuthTransformed:
|
||||
AuthenticateLastConfidentialBlock();
|
||||
m_bufferedDataLength = 0;
|
||||
m_state = State_AuthFooter;
|
||||
// fall through
|
||||
case State_AuthFooter:
|
||||
AuthenticateData(input, length);
|
||||
m_totalFooterLength += length;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::ProcessData(byte *outString, const byte *inString, size_t length)
|
||||
{
|
||||
m_totalMessageLength += length;
|
||||
if (m_state >= State_IVSet && m_totalMessageLength > MaxMessageLength())
|
||||
throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");
|
||||
|
||||
reswitch:
|
||||
switch (m_state)
|
||||
{
|
||||
case State_Start:
|
||||
case State_KeySet:
|
||||
throw BadState(AlgorithmName(), "ProcessData", "setting key and IV");
|
||||
case State_AuthFooter:
|
||||
throw BadState(AlgorithmName(), "ProcessData was called after footer input has started");
|
||||
case State_IVSet:
|
||||
AuthenticateLastHeaderBlock();
|
||||
m_bufferedDataLength = 0;
|
||||
m_state = AuthenticationIsOnPlaintext()==IsForwardTransformation() ? State_AuthUntransformed : State_AuthTransformed;
|
||||
goto reswitch;
|
||||
case State_AuthUntransformed:
|
||||
AuthenticateData(inString, length);
|
||||
AccessSymmetricCipher().ProcessData(outString, inString, length);
|
||||
break;
|
||||
case State_AuthTransformed:
|
||||
AccessSymmetricCipher().ProcessData(outString, inString, length);
|
||||
AuthenticateData(outString, length);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::TruncatedFinal(byte *mac, size_t macSize)
|
||||
{
|
||||
if (m_totalHeaderLength > MaxHeaderLength())
|
||||
throw InvalidArgument(AlgorithmName() + ": header length of " + IntToString(m_totalHeaderLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));
|
||||
|
||||
if (m_totalFooterLength > MaxFooterLength())
|
||||
{
|
||||
if (MaxFooterLength() == 0)
|
||||
throw InvalidArgument(AlgorithmName() + ": additional authenticated data (AAD) cannot be input after data to be encrypted or decrypted");
|
||||
else
|
||||
throw InvalidArgument(AlgorithmName() + ": footer length of " + IntToString(m_totalFooterLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));
|
||||
}
|
||||
|
||||
switch (m_state)
|
||||
{
|
||||
case State_Start:
|
||||
case State_KeySet:
|
||||
throw BadState(AlgorithmName(), "TruncatedFinal", "setting key and IV");
|
||||
|
||||
case State_IVSet:
|
||||
AuthenticateLastHeaderBlock();
|
||||
m_bufferedDataLength = 0;
|
||||
// fall through
|
||||
|
||||
case State_AuthUntransformed:
|
||||
case State_AuthTransformed:
|
||||
AuthenticateLastConfidentialBlock();
|
||||
m_bufferedDataLength = 0;
|
||||
// fall through
|
||||
|
||||
case State_AuthFooter:
|
||||
AuthenticateLastFooterBlock(mac, macSize);
|
||||
m_bufferedDataLength = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
m_state = State_KeySet;
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
// authenc.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#ifndef CRYPTOPP_IMPORTS
|
||||
|
||||
#include "authenc.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::AuthenticateData(const byte *input, size_t len)
|
||||
{
|
||||
unsigned int blockSize = AuthenticationBlockSize();
|
||||
unsigned int &num = m_bufferedDataLength;
|
||||
byte* data = m_buffer.begin();
|
||||
|
||||
if (num != 0) // process left over data
|
||||
{
|
||||
if (num+len >= blockSize)
|
||||
{
|
||||
memcpy(data+num, input, blockSize-num);
|
||||
AuthenticateBlocks(data, blockSize);
|
||||
input += (blockSize-num);
|
||||
len -= (blockSize-num);
|
||||
num = 0;
|
||||
// drop through and do the rest
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(data+num, input, len);
|
||||
num += (unsigned int)len;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// now process the input data in blocks of blockSize bytes and save the leftovers to m_data
|
||||
if (len >= blockSize)
|
||||
{
|
||||
size_t leftOver = AuthenticateBlocks(input, len);
|
||||
input += (len - leftOver);
|
||||
len = leftOver;
|
||||
}
|
||||
|
||||
memcpy(data, input, len);
|
||||
num = (unsigned int)len;
|
||||
}
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::SetKey(const byte *userKey, size_t keylength, const NameValuePairs ¶ms)
|
||||
{
|
||||
m_bufferedDataLength = 0;
|
||||
m_state = State_Start;
|
||||
|
||||
SetKeyWithoutResync(userKey, keylength, params);
|
||||
m_state = State_KeySet;
|
||||
|
||||
size_t length;
|
||||
const byte *iv = GetIVAndThrowIfInvalid(params, length);
|
||||
if (iv)
|
||||
Resynchronize(iv, (int)length);
|
||||
}
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::Resynchronize(const byte *iv, int length)
|
||||
{
|
||||
if (m_state < State_KeySet)
|
||||
throw BadState(AlgorithmName(), "Resynchronize", "key is set");
|
||||
|
||||
m_bufferedDataLength = 0;
|
||||
m_totalHeaderLength = m_totalMessageLength = m_totalFooterLength = 0;
|
||||
m_state = State_KeySet;
|
||||
|
||||
Resync(iv, this->ThrowIfInvalidIVLength(length));
|
||||
m_state = State_IVSet;
|
||||
}
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::Update(const byte *input, size_t length)
|
||||
{
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
switch (m_state)
|
||||
{
|
||||
case State_Start:
|
||||
case State_KeySet:
|
||||
throw BadState(AlgorithmName(), "Update", "setting key and IV");
|
||||
case State_IVSet:
|
||||
AuthenticateData(input, length);
|
||||
m_totalHeaderLength += length;
|
||||
break;
|
||||
case State_AuthUntransformed:
|
||||
case State_AuthTransformed:
|
||||
AuthenticateLastConfidentialBlock();
|
||||
m_bufferedDataLength = 0;
|
||||
m_state = State_AuthFooter;
|
||||
// fall through
|
||||
case State_AuthFooter:
|
||||
AuthenticateData(input, length);
|
||||
m_totalFooterLength += length;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::ProcessData(byte *outString, const byte *inString, size_t length)
|
||||
{
|
||||
m_totalMessageLength += length;
|
||||
if (m_state >= State_IVSet && m_totalMessageLength > MaxMessageLength())
|
||||
throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");
|
||||
|
||||
reswitch:
|
||||
switch (m_state)
|
||||
{
|
||||
case State_Start:
|
||||
case State_KeySet:
|
||||
throw BadState(AlgorithmName(), "ProcessData", "setting key and IV");
|
||||
case State_AuthFooter:
|
||||
throw BadState(AlgorithmName(), "ProcessData was called after footer input has started");
|
||||
case State_IVSet:
|
||||
AuthenticateLastHeaderBlock();
|
||||
m_bufferedDataLength = 0;
|
||||
m_state = AuthenticationIsOnPlaintext()==IsForwardTransformation() ? State_AuthUntransformed : State_AuthTransformed;
|
||||
goto reswitch;
|
||||
case State_AuthUntransformed:
|
||||
AuthenticateData(inString, length);
|
||||
AccessSymmetricCipher().ProcessData(outString, inString, length);
|
||||
break;
|
||||
case State_AuthTransformed:
|
||||
AccessSymmetricCipher().ProcessData(outString, inString, length);
|
||||
AuthenticateData(outString, length);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AuthenticatedSymmetricCipherBase::TruncatedFinal(byte *mac, size_t macSize)
|
||||
{
|
||||
if (m_totalHeaderLength > MaxHeaderLength())
|
||||
throw InvalidArgument(AlgorithmName() + ": header length of " + IntToString(m_totalHeaderLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));
|
||||
|
||||
if (m_totalFooterLength > MaxFooterLength())
|
||||
{
|
||||
if (MaxFooterLength() == 0)
|
||||
throw InvalidArgument(AlgorithmName() + ": additional authenticated data (AAD) cannot be input after data to be encrypted or decrypted");
|
||||
else
|
||||
throw InvalidArgument(AlgorithmName() + ": footer length of " + IntToString(m_totalFooterLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));
|
||||
}
|
||||
|
||||
switch (m_state)
|
||||
{
|
||||
case State_Start:
|
||||
case State_KeySet:
|
||||
throw BadState(AlgorithmName(), "TruncatedFinal", "setting key and IV");
|
||||
|
||||
case State_IVSet:
|
||||
AuthenticateLastHeaderBlock();
|
||||
m_bufferedDataLength = 0;
|
||||
// fall through
|
||||
|
||||
case State_AuthUntransformed:
|
||||
case State_AuthTransformed:
|
||||
AuthenticateLastConfidentialBlock();
|
||||
m_bufferedDataLength = 0;
|
||||
// fall through
|
||||
|
||||
case State_AuthFooter:
|
||||
AuthenticateLastFooterBlock(mac, macSize);
|
||||
m_bufferedDataLength = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
m_state = State_KeySet;
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
@ -1,49 +1,49 @@
|
||||
#ifndef CRYPTOPP_AUTHENC_H
|
||||
#define CRYPTOPP_AUTHENC_H
|
||||
|
||||
#include "cryptlib.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! .
|
||||
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipherBase : public AuthenticatedSymmetricCipher
|
||||
{
|
||||
public:
|
||||
AuthenticatedSymmetricCipherBase() : m_state(State_Start) {}
|
||||
|
||||
bool IsRandomAccess() const {return false;}
|
||||
bool IsSelfInverting() const {return true;}
|
||||
void UncheckedSetKey(const byte *,unsigned int,const CryptoPP::NameValuePairs &) {assert(false);}
|
||||
|
||||
void SetKey(const byte *userKey, size_t keylength, const NameValuePairs ¶ms);
|
||||
void Restart() {if (m_state > State_KeySet) m_state = State_KeySet;}
|
||||
void Resynchronize(const byte *iv, int length=-1);
|
||||
void Update(const byte *input, size_t length);
|
||||
void ProcessData(byte *outString, const byte *inString, size_t length);
|
||||
void TruncatedFinal(byte *mac, size_t macSize);
|
||||
|
||||
protected:
|
||||
void AuthenticateData(const byte *data, size_t len);
|
||||
const SymmetricCipher & GetSymmetricCipher() const {return const_cast<AuthenticatedSymmetricCipherBase *>(this)->AccessSymmetricCipher();};
|
||||
|
||||
virtual SymmetricCipher & AccessSymmetricCipher() =0;
|
||||
virtual bool AuthenticationIsOnPlaintext() const =0;
|
||||
virtual unsigned int AuthenticationBlockSize() const =0;
|
||||
virtual void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) =0;
|
||||
virtual void Resync(const byte *iv, size_t len) =0;
|
||||
virtual size_t AuthenticateBlocks(const byte *data, size_t len) =0;
|
||||
virtual void AuthenticateLastHeaderBlock() =0;
|
||||
virtual void AuthenticateLastConfidentialBlock() {}
|
||||
virtual void AuthenticateLastFooterBlock(byte *mac, size_t macSize) =0;
|
||||
|
||||
enum State {State_Start, State_KeySet, State_IVSet, State_AuthUntransformed, State_AuthTransformed, State_AuthFooter};
|
||||
State m_state;
|
||||
unsigned int m_bufferedDataLength;
|
||||
lword m_totalHeaderLength, m_totalMessageLength, m_totalFooterLength;
|
||||
AlignedSecByteBlock m_buffer;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
#ifndef CRYPTOPP_AUTHENC_H
|
||||
#define CRYPTOPP_AUTHENC_H
|
||||
|
||||
#include "cryptlib.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! .
|
||||
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipherBase : public AuthenticatedSymmetricCipher
|
||||
{
|
||||
public:
|
||||
AuthenticatedSymmetricCipherBase() : m_state(State_Start) {}
|
||||
|
||||
bool IsRandomAccess() const {return false;}
|
||||
bool IsSelfInverting() const {return true;}
|
||||
void UncheckedSetKey(const byte *,unsigned int,const CryptoPP::NameValuePairs &) {assert(false);}
|
||||
|
||||
void SetKey(const byte *userKey, size_t keylength, const NameValuePairs ¶ms);
|
||||
void Restart() {if (m_state > State_KeySet) m_state = State_KeySet;}
|
||||
void Resynchronize(const byte *iv, int length=-1);
|
||||
void Update(const byte *input, size_t length);
|
||||
void ProcessData(byte *outString, const byte *inString, size_t length);
|
||||
void TruncatedFinal(byte *mac, size_t macSize);
|
||||
|
||||
protected:
|
||||
void AuthenticateData(const byte *data, size_t len);
|
||||
const SymmetricCipher & GetSymmetricCipher() const {return const_cast<AuthenticatedSymmetricCipherBase *>(this)->AccessSymmetricCipher();};
|
||||
|
||||
virtual SymmetricCipher & AccessSymmetricCipher() =0;
|
||||
virtual bool AuthenticationIsOnPlaintext() const =0;
|
||||
virtual unsigned int AuthenticationBlockSize() const =0;
|
||||
virtual void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) =0;
|
||||
virtual void Resync(const byte *iv, size_t len) =0;
|
||||
virtual size_t AuthenticateBlocks(const byte *data, size_t len) =0;
|
||||
virtual void AuthenticateLastHeaderBlock() =0;
|
||||
virtual void AuthenticateLastConfidentialBlock() {}
|
||||
virtual void AuthenticateLastFooterBlock(byte *mac, size_t macSize) =0;
|
||||
|
||||
enum State {State_Start, State_KeySet, State_IVSet, State_AuthUntransformed, State_AuthTransformed, State_AuthFooter};
|
||||
State m_state;
|
||||
unsigned int m_bufferedDataLength;
|
||||
lword m_totalHeaderLength, m_totalMessageLength, m_totalFooterLength;
|
||||
AlignedSecByteBlock m_buffer;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
280
CryptoPP/ccm.cpp
280
CryptoPP/ccm.cpp
@ -1,140 +1,140 @@
|
||||
// ccm.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#ifndef CRYPTOPP_IMPORTS
|
||||
|
||||
#include "ccm.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void CCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms)
|
||||
{
|
||||
BlockCipher &blockCipher = AccessBlockCipher();
|
||||
|
||||
blockCipher.SetKey(userKey, keylength, params);
|
||||
|
||||
if (blockCipher.BlockSize() != REQUIRED_BLOCKSIZE)
|
||||
throw InvalidArgument(AlgorithmName() + ": block size of underlying block cipher is not 16");
|
||||
|
||||
m_digestSize = params.GetIntValueWithDefault(Name::DigestSize(), DefaultDigestSize());
|
||||
if (m_digestSize % 2 > 0 || m_digestSize < 4 || m_digestSize > 16)
|
||||
throw InvalidArgument(AlgorithmName() + ": DigestSize must be 4, 6, 8, 10, 12, 14, or 16");
|
||||
|
||||
m_buffer.Grow(2*REQUIRED_BLOCKSIZE);
|
||||
m_L = 8;
|
||||
}
|
||||
|
||||
void CCM_Base::Resync(const byte *iv, size_t len)
|
||||
{
|
||||
BlockCipher &cipher = AccessBlockCipher();
|
||||
|
||||
m_L = REQUIRED_BLOCKSIZE-1-(int)len;
|
||||
assert(m_L >= 2);
|
||||
if (m_L > 8)
|
||||
m_L = 8;
|
||||
|
||||
m_buffer[0] = byte(m_L-1); // flag
|
||||
memcpy(m_buffer+1, iv, len);
|
||||
memset(m_buffer+1+len, 0, REQUIRED_BLOCKSIZE-1-len);
|
||||
|
||||
if (m_state >= State_IVSet)
|
||||
m_ctr.Resynchronize(m_buffer, REQUIRED_BLOCKSIZE);
|
||||
else
|
||||
m_ctr.SetCipherWithIV(cipher, m_buffer);
|
||||
|
||||
m_ctr.Seek(REQUIRED_BLOCKSIZE);
|
||||
m_aadLength = 0;
|
||||
m_messageLength = 0;
|
||||
}
|
||||
|
||||
void CCM_Base::UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength)
|
||||
{
|
||||
if (m_state != State_IVSet)
|
||||
throw BadState(AlgorithmName(), "SpecifyDataLengths", "or after State_IVSet");
|
||||
|
||||
m_aadLength = headerLength;
|
||||
m_messageLength = messageLength;
|
||||
|
||||
byte *cbcBuffer = CBC_Buffer();
|
||||
const BlockCipher &cipher = GetBlockCipher();
|
||||
|
||||
cbcBuffer[0] = byte(64*(headerLength>0) + 8*((m_digestSize-2)/2) + (m_L-1)); // flag
|
||||
PutWord<word64>(true, BIG_ENDIAN_ORDER, cbcBuffer+REQUIRED_BLOCKSIZE-8, m_messageLength);
|
||||
memcpy(cbcBuffer+1, m_buffer+1, REQUIRED_BLOCKSIZE-1-m_L);
|
||||
cipher.ProcessBlock(cbcBuffer);
|
||||
|
||||
if (headerLength>0)
|
||||
{
|
||||
assert(m_bufferedDataLength == 0);
|
||||
|
||||
if (headerLength < ((1<<16) - (1<<8)))
|
||||
{
|
||||
PutWord<word16>(true, BIG_ENDIAN_ORDER, m_buffer, (word16)headerLength);
|
||||
m_bufferedDataLength = 2;
|
||||
}
|
||||
else if (headerLength < (W64LIT(1)<<32))
|
||||
{
|
||||
m_buffer[0] = 0xff;
|
||||
m_buffer[1] = 0xfe;
|
||||
PutWord<word32>(false, BIG_ENDIAN_ORDER, m_buffer+2, (word32)headerLength);
|
||||
m_bufferedDataLength = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buffer[0] = 0xff;
|
||||
m_buffer[1] = 0xff;
|
||||
PutWord<word64>(false, BIG_ENDIAN_ORDER, m_buffer+2, headerLength);
|
||||
m_bufferedDataLength = 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t CCM_Base::AuthenticateBlocks(const byte *data, size_t len)
|
||||
{
|
||||
byte *cbcBuffer = CBC_Buffer();
|
||||
const BlockCipher &cipher = GetBlockCipher();
|
||||
return cipher.AdvancedProcessBlocks(cbcBuffer, data, cbcBuffer, len, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);
|
||||
}
|
||||
|
||||
void CCM_Base::AuthenticateLastHeaderBlock()
|
||||
{
|
||||
byte *cbcBuffer = CBC_Buffer();
|
||||
const BlockCipher &cipher = GetBlockCipher();
|
||||
|
||||
if (m_aadLength != m_totalHeaderLength)
|
||||
throw InvalidArgument(AlgorithmName() + ": header length doesn't match that given in SpecifyDataLengths");
|
||||
|
||||
if (m_bufferedDataLength > 0)
|
||||
{
|
||||
xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength);
|
||||
cipher.ProcessBlock(cbcBuffer);
|
||||
m_bufferedDataLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CCM_Base::AuthenticateLastConfidentialBlock()
|
||||
{
|
||||
byte *cbcBuffer = CBC_Buffer();
|
||||
const BlockCipher &cipher = GetBlockCipher();
|
||||
|
||||
if (m_messageLength != m_totalMessageLength)
|
||||
throw InvalidArgument(AlgorithmName() + ": message length doesn't match that given in SpecifyDataLengths");
|
||||
|
||||
if (m_bufferedDataLength > 0)
|
||||
{
|
||||
xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength);
|
||||
cipher.ProcessBlock(cbcBuffer);
|
||||
m_bufferedDataLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CCM_Base::AuthenticateLastFooterBlock(byte *mac, size_t macSize)
|
||||
{
|
||||
m_ctr.Seek(0);
|
||||
m_ctr.ProcessData(mac, CBC_Buffer(), macSize);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
// ccm.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#ifndef CRYPTOPP_IMPORTS
|
||||
|
||||
#include "ccm.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void CCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms)
|
||||
{
|
||||
BlockCipher &blockCipher = AccessBlockCipher();
|
||||
|
||||
blockCipher.SetKey(userKey, keylength, params);
|
||||
|
||||
if (blockCipher.BlockSize() != REQUIRED_BLOCKSIZE)
|
||||
throw InvalidArgument(AlgorithmName() + ": block size of underlying block cipher is not 16");
|
||||
|
||||
m_digestSize = params.GetIntValueWithDefault(Name::DigestSize(), DefaultDigestSize());
|
||||
if (m_digestSize % 2 > 0 || m_digestSize < 4 || m_digestSize > 16)
|
||||
throw InvalidArgument(AlgorithmName() + ": DigestSize must be 4, 6, 8, 10, 12, 14, or 16");
|
||||
|
||||
m_buffer.Grow(2*REQUIRED_BLOCKSIZE);
|
||||
m_L = 8;
|
||||
}
|
||||
|
||||
void CCM_Base::Resync(const byte *iv, size_t len)
|
||||
{
|
||||
BlockCipher &cipher = AccessBlockCipher();
|
||||
|
||||
m_L = REQUIRED_BLOCKSIZE-1-(int)len;
|
||||
assert(m_L >= 2);
|
||||
if (m_L > 8)
|
||||
m_L = 8;
|
||||
|
||||
m_buffer[0] = byte(m_L-1); // flag
|
||||
memcpy(m_buffer+1, iv, len);
|
||||
memset(m_buffer+1+len, 0, REQUIRED_BLOCKSIZE-1-len);
|
||||
|
||||
if (m_state >= State_IVSet)
|
||||
m_ctr.Resynchronize(m_buffer, REQUIRED_BLOCKSIZE);
|
||||
else
|
||||
m_ctr.SetCipherWithIV(cipher, m_buffer);
|
||||
|
||||
m_ctr.Seek(REQUIRED_BLOCKSIZE);
|
||||
m_aadLength = 0;
|
||||
m_messageLength = 0;
|
||||
}
|
||||
|
||||
void CCM_Base::UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength)
|
||||
{
|
||||
if (m_state != State_IVSet)
|
||||
throw BadState(AlgorithmName(), "SpecifyDataLengths", "or after State_IVSet");
|
||||
|
||||
m_aadLength = headerLength;
|
||||
m_messageLength = messageLength;
|
||||
|
||||
byte *cbcBuffer = CBC_Buffer();
|
||||
const BlockCipher &cipher = GetBlockCipher();
|
||||
|
||||
cbcBuffer[0] = byte(64*(headerLength>0) + 8*((m_digestSize-2)/2) + (m_L-1)); // flag
|
||||
PutWord<word64>(true, BIG_ENDIAN_ORDER, cbcBuffer+REQUIRED_BLOCKSIZE-8, m_messageLength);
|
||||
memcpy(cbcBuffer+1, m_buffer+1, REQUIRED_BLOCKSIZE-1-m_L);
|
||||
cipher.ProcessBlock(cbcBuffer);
|
||||
|
||||
if (headerLength>0)
|
||||
{
|
||||
assert(m_bufferedDataLength == 0);
|
||||
|
||||
if (headerLength < ((1<<16) - (1<<8)))
|
||||
{
|
||||
PutWord<word16>(true, BIG_ENDIAN_ORDER, m_buffer, (word16)headerLength);
|
||||
m_bufferedDataLength = 2;
|
||||
}
|
||||
else if (headerLength < (W64LIT(1)<<32))
|
||||
{
|
||||
m_buffer[0] = 0xff;
|
||||
m_buffer[1] = 0xfe;
|
||||
PutWord<word32>(false, BIG_ENDIAN_ORDER, m_buffer+2, (word32)headerLength);
|
||||
m_bufferedDataLength = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buffer[0] = 0xff;
|
||||
m_buffer[1] = 0xff;
|
||||
PutWord<word64>(false, BIG_ENDIAN_ORDER, m_buffer+2, headerLength);
|
||||
m_bufferedDataLength = 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t CCM_Base::AuthenticateBlocks(const byte *data, size_t len)
|
||||
{
|
||||
byte *cbcBuffer = CBC_Buffer();
|
||||
const BlockCipher &cipher = GetBlockCipher();
|
||||
return cipher.AdvancedProcessBlocks(cbcBuffer, data, cbcBuffer, len, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);
|
||||
}
|
||||
|
||||
void CCM_Base::AuthenticateLastHeaderBlock()
|
||||
{
|
||||
byte *cbcBuffer = CBC_Buffer();
|
||||
const BlockCipher &cipher = GetBlockCipher();
|
||||
|
||||
if (m_aadLength != m_totalHeaderLength)
|
||||
throw InvalidArgument(AlgorithmName() + ": header length doesn't match that given in SpecifyDataLengths");
|
||||
|
||||
if (m_bufferedDataLength > 0)
|
||||
{
|
||||
xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength);
|
||||
cipher.ProcessBlock(cbcBuffer);
|
||||
m_bufferedDataLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CCM_Base::AuthenticateLastConfidentialBlock()
|
||||
{
|
||||
byte *cbcBuffer = CBC_Buffer();
|
||||
const BlockCipher &cipher = GetBlockCipher();
|
||||
|
||||
if (m_messageLength != m_totalMessageLength)
|
||||
throw InvalidArgument(AlgorithmName() + ": message length doesn't match that given in SpecifyDataLengths");
|
||||
|
||||
if (m_bufferedDataLength > 0)
|
||||
{
|
||||
xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength);
|
||||
cipher.ProcessBlock(cbcBuffer);
|
||||
m_bufferedDataLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CCM_Base::AuthenticateLastFooterBlock(byte *mac, size_t macSize)
|
||||
{
|
||||
m_ctr.Seek(0);
|
||||
m_ctr.ProcessData(mac, CBC_Buffer(), macSize);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
202
CryptoPP/ccm.h
202
CryptoPP/ccm.h
@ -1,101 +1,101 @@
|
||||
#ifndef CRYPTOPP_CCM_H
|
||||
#define CRYPTOPP_CCM_H
|
||||
|
||||
#include "authenc.h"
|
||||
#include "modes.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! .
|
||||
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CCM_Base : public AuthenticatedSymmetricCipherBase
|
||||
{
|
||||
public:
|
||||
CCM_Base()
|
||||
: m_digestSize(0), m_L(0) {}
|
||||
|
||||
// AuthenticatedSymmetricCipher
|
||||
std::string AlgorithmName() const
|
||||
{return GetBlockCipher().AlgorithmName() + std::string("/CCM");}
|
||||
size_t MinKeyLength() const
|
||||
{return GetBlockCipher().MinKeyLength();}
|
||||
size_t MaxKeyLength() const
|
||||
{return GetBlockCipher().MaxKeyLength();}
|
||||
size_t DefaultKeyLength() const
|
||||
{return GetBlockCipher().DefaultKeyLength();}
|
||||
size_t GetValidKeyLength(size_t n) const
|
||||
{return GetBlockCipher().GetValidKeyLength(n);}
|
||||
bool IsValidKeyLength(size_t n) const
|
||||
{return GetBlockCipher().IsValidKeyLength(n);}
|
||||
unsigned int OptimalDataAlignment() const
|
||||
{return GetBlockCipher().OptimalDataAlignment();}
|
||||
IV_Requirement IVRequirement() const
|
||||
{return UNIQUE_IV;}
|
||||
unsigned int IVSize() const
|
||||
{return 8;}
|
||||
unsigned int MinIVLength() const
|
||||
{return 7;}
|
||||
unsigned int MaxIVLength() const
|
||||
{return 13;}
|
||||
unsigned int DigestSize() const
|
||||
{return m_digestSize;}
|
||||
lword MaxHeaderLength() const
|
||||
{return W64LIT(0)-1;}
|
||||
lword MaxMessageLength() const
|
||||
{return m_L<8 ? (W64LIT(1)<<(8*m_L))-1 : W64LIT(0)-1;}
|
||||
bool NeedsPrespecifiedDataLengths() const
|
||||
{return true;}
|
||||
void UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength);
|
||||
|
||||
protected:
|
||||
// AuthenticatedSymmetricCipherBase
|
||||
bool AuthenticationIsOnPlaintext() const
|
||||
{return true;}
|
||||
unsigned int AuthenticationBlockSize() const
|
||||
{return GetBlockCipher().BlockSize();}
|
||||
void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms);
|
||||
void Resync(const byte *iv, size_t len);
|
||||
size_t AuthenticateBlocks(const byte *data, size_t len);
|
||||
void AuthenticateLastHeaderBlock();
|
||||
void AuthenticateLastConfidentialBlock();
|
||||
void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
|
||||
SymmetricCipher & AccessSymmetricCipher() {return m_ctr;}
|
||||
|
||||
virtual BlockCipher & AccessBlockCipher() =0;
|
||||
virtual int DefaultDigestSize() const =0;
|
||||
|
||||
const BlockCipher & GetBlockCipher() const {return const_cast<CCM_Base *>(this)->AccessBlockCipher();};
|
||||
byte *CBC_Buffer() {return m_buffer+REQUIRED_BLOCKSIZE;}
|
||||
|
||||
enum {REQUIRED_BLOCKSIZE = 16};
|
||||
int m_digestSize, m_L;
|
||||
word64 m_messageLength, m_aadLength;
|
||||
CTR_Mode_ExternalCipher::Encryption m_ctr;
|
||||
};
|
||||
|
||||
//! .
|
||||
template <class T_BlockCipher, int T_DefaultDigestSize, bool T_IsEncryption>
|
||||
class CCM_Final : public CCM_Base
|
||||
{
|
||||
public:
|
||||
static std::string StaticAlgorithmName()
|
||||
{return T_BlockCipher::StaticAlgorithmName() + std::string("/CCM");}
|
||||
bool IsForwardTransformation() const
|
||||
{return T_IsEncryption;}
|
||||
|
||||
private:
|
||||
BlockCipher & AccessBlockCipher() {return m_cipher;}
|
||||
int DefaultDigestSize() const {return T_DefaultDigestSize;}
|
||||
typename T_BlockCipher::Encryption m_cipher;
|
||||
};
|
||||
|
||||
/// <a href="http://www.cryptolounge.org/wiki/CCM">CCM</a>
|
||||
template <class T_BlockCipher, int T_DefaultDigestSize = 16>
|
||||
struct CCM : public AuthenticatedSymmetricCipherDocumentation
|
||||
{
|
||||
typedef CCM_Final<T_BlockCipher, T_DefaultDigestSize, true> Encryption;
|
||||
typedef CCM_Final<T_BlockCipher, T_DefaultDigestSize, false> Decryption;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
#ifndef CRYPTOPP_CCM_H
|
||||
#define CRYPTOPP_CCM_H
|
||||
|
||||
#include "authenc.h"
|
||||
#include "modes.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! .
|
||||
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CCM_Base : public AuthenticatedSymmetricCipherBase
|
||||
{
|
||||
public:
|
||||
CCM_Base()
|
||||
: m_digestSize(0), m_L(0) {}
|
||||
|
||||
// AuthenticatedSymmetricCipher
|
||||
std::string AlgorithmName() const
|
||||
{return GetBlockCipher().AlgorithmName() + std::string("/CCM");}
|
||||
size_t MinKeyLength() const
|
||||
{return GetBlockCipher().MinKeyLength();}
|
||||
size_t MaxKeyLength() const
|
||||
{return GetBlockCipher().MaxKeyLength();}
|
||||
size_t DefaultKeyLength() const
|
||||
{return GetBlockCipher().DefaultKeyLength();}
|
||||
size_t GetValidKeyLength(size_t n) const
|
||||
{return GetBlockCipher().GetValidKeyLength(n);}
|
||||
bool IsValidKeyLength(size_t n) const
|
||||
{return GetBlockCipher().IsValidKeyLength(n);}
|
||||
unsigned int OptimalDataAlignment() const
|
||||
{return GetBlockCipher().OptimalDataAlignment();}
|
||||
IV_Requirement IVRequirement() const
|
||||
{return UNIQUE_IV;}
|
||||
unsigned int IVSize() const
|
||||
{return 8;}
|
||||
unsigned int MinIVLength() const
|
||||
{return 7;}
|
||||
unsigned int MaxIVLength() const
|
||||
{return 13;}
|
||||
unsigned int DigestSize() const
|
||||
{return m_digestSize;}
|
||||
lword MaxHeaderLength() const
|
||||
{return W64LIT(0)-1;}
|
||||
lword MaxMessageLength() const
|
||||
{return m_L<8 ? (W64LIT(1)<<(8*m_L))-1 : W64LIT(0)-1;}
|
||||
bool NeedsPrespecifiedDataLengths() const
|
||||
{return true;}
|
||||
void UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength);
|
||||
|
||||
protected:
|
||||
// AuthenticatedSymmetricCipherBase
|
||||
bool AuthenticationIsOnPlaintext() const
|
||||
{return true;}
|
||||
unsigned int AuthenticationBlockSize() const
|
||||
{return GetBlockCipher().BlockSize();}
|
||||
void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms);
|
||||
void Resync(const byte *iv, size_t len);
|
||||
size_t AuthenticateBlocks(const byte *data, size_t len);
|
||||
void AuthenticateLastHeaderBlock();
|
||||
void AuthenticateLastConfidentialBlock();
|
||||
void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
|
||||
SymmetricCipher & AccessSymmetricCipher() {return m_ctr;}
|
||||
|
||||
virtual BlockCipher & AccessBlockCipher() =0;
|
||||
virtual int DefaultDigestSize() const =0;
|
||||
|
||||
const BlockCipher & GetBlockCipher() const {return const_cast<CCM_Base *>(this)->AccessBlockCipher();};
|
||||
byte *CBC_Buffer() {return m_buffer+REQUIRED_BLOCKSIZE;}
|
||||
|
||||
enum {REQUIRED_BLOCKSIZE = 16};
|
||||
int m_digestSize, m_L;
|
||||
word64 m_messageLength, m_aadLength;
|
||||
CTR_Mode_ExternalCipher::Encryption m_ctr;
|
||||
};
|
||||
|
||||
//! .
|
||||
template <class T_BlockCipher, int T_DefaultDigestSize, bool T_IsEncryption>
|
||||
class CCM_Final : public CCM_Base
|
||||
{
|
||||
public:
|
||||
static std::string StaticAlgorithmName()
|
||||
{return T_BlockCipher::StaticAlgorithmName() + std::string("/CCM");}
|
||||
bool IsForwardTransformation() const
|
||||
{return T_IsEncryption;}
|
||||
|
||||
private:
|
||||
BlockCipher & AccessBlockCipher() {return m_cipher;}
|
||||
int DefaultDigestSize() const {return T_DefaultDigestSize;}
|
||||
typename T_BlockCipher::Encryption m_cipher;
|
||||
};
|
||||
|
||||
/// <a href="http://www.cryptolounge.org/wiki/CCM">CCM</a>
|
||||
template <class T_BlockCipher, int T_DefaultDigestSize = 16>
|
||||
struct CCM : public AuthenticatedSymmetricCipherDocumentation
|
||||
{
|
||||
typedef CCM_Final<T_BlockCipher, T_DefaultDigestSize, true> Encryption;
|
||||
typedef CCM_Final<T_BlockCipher, T_DefaultDigestSize, false> Decryption;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
@ -1,122 +1,122 @@
|
||||
// cmac.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#ifndef CRYPTOPP_IMPORTS
|
||||
|
||||
#include "cmac.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
static void MulU(byte *k, unsigned int length)
|
||||
{
|
||||
byte carry = 0;
|
||||
|
||||
for (int i=length-1; i>=1; i-=2)
|
||||
{
|
||||
byte carry2 = k[i] >> 7;
|
||||
k[i] += k[i] + carry;
|
||||
carry = k[i-1] >> 7;
|
||||
k[i-1] += k[i-1] + carry2;
|
||||
}
|
||||
|
||||
if (carry)
|
||||
{
|
||||
switch (length)
|
||||
{
|
||||
case 8:
|
||||
k[7] ^= 0x1b;
|
||||
break;
|
||||
case 16:
|
||||
k[15] ^= 0x87;
|
||||
break;
|
||||
case 32:
|
||||
k[30] ^= 4;
|
||||
k[31] ^= 0x23;
|
||||
break;
|
||||
default:
|
||||
throw InvalidArgument("CMAC: " + IntToString(length) + " is not a supported cipher block size");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)
|
||||
{
|
||||
BlockCipher &cipher = AccessCipher();
|
||||
unsigned int blockSize = cipher.BlockSize();
|
||||
|
||||
cipher.SetKey(key, length, params);
|
||||
m_reg.CleanNew(3*blockSize);
|
||||
m_counter = 0;
|
||||
|
||||
cipher.ProcessBlock(m_reg, m_reg+blockSize);
|
||||
MulU(m_reg+blockSize, blockSize);
|
||||
memcpy(m_reg+2*blockSize, m_reg+blockSize, blockSize);
|
||||
MulU(m_reg+2*blockSize, blockSize);
|
||||
}
|
||||
|
||||
void CMAC_Base::Update(const byte *input, size_t length)
|
||||
{
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
BlockCipher &cipher = AccessCipher();
|
||||
unsigned int blockSize = cipher.BlockSize();
|
||||
|
||||
if (m_counter > 0)
|
||||
{
|
||||
unsigned int len = UnsignedMin(blockSize - m_counter, length);
|
||||
xorbuf(m_reg+m_counter, input, len);
|
||||
length -= len;
|
||||
input += len;
|
||||
m_counter += len;
|
||||
|
||||
if (m_counter == blockSize && length > 0)
|
||||
{
|
||||
cipher.ProcessBlock(m_reg);
|
||||
m_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (length > blockSize)
|
||||
{
|
||||
assert(m_counter == 0);
|
||||
size_t leftOver = 1 + cipher.AdvancedProcessBlocks(m_reg, input, m_reg, length-1, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);
|
||||
input += (length - leftOver);
|
||||
length = leftOver;
|
||||
}
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
assert(m_counter + length <= blockSize);
|
||||
xorbuf(m_reg+m_counter, input, length);
|
||||
m_counter += (unsigned int)length;
|
||||
}
|
||||
|
||||
assert(m_counter > 0);
|
||||
}
|
||||
|
||||
void CMAC_Base::TruncatedFinal(byte *mac, size_t size)
|
||||
{
|
||||
ThrowIfInvalidTruncatedSize(size);
|
||||
|
||||
BlockCipher &cipher = AccessCipher();
|
||||
unsigned int blockSize = cipher.BlockSize();
|
||||
|
||||
if (m_counter < blockSize)
|
||||
{
|
||||
m_reg[m_counter] ^= 0x80;
|
||||
cipher.AdvancedProcessBlocks(m_reg, m_reg+2*blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);
|
||||
}
|
||||
else
|
||||
cipher.AdvancedProcessBlocks(m_reg, m_reg+blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);
|
||||
|
||||
memcpy(mac, m_reg, size);
|
||||
|
||||
m_counter = 0;
|
||||
memset(m_reg, 0, blockSize);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
// cmac.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#ifndef CRYPTOPP_IMPORTS
|
||||
|
||||
#include "cmac.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
static void MulU(byte *k, unsigned int length)
|
||||
{
|
||||
byte carry = 0;
|
||||
|
||||
for (int i=length-1; i>=1; i-=2)
|
||||
{
|
||||
byte carry2 = k[i] >> 7;
|
||||
k[i] += k[i] + carry;
|
||||
carry = k[i-1] >> 7;
|
||||
k[i-1] += k[i-1] + carry2;
|
||||
}
|
||||
|
||||
if (carry)
|
||||
{
|
||||
switch (length)
|
||||
{
|
||||
case 8:
|
||||
k[7] ^= 0x1b;
|
||||
break;
|
||||
case 16:
|
||||
k[15] ^= 0x87;
|
||||
break;
|
||||
case 32:
|
||||
k[30] ^= 4;
|
||||
k[31] ^= 0x23;
|
||||
break;
|
||||
default:
|
||||
throw InvalidArgument("CMAC: " + IntToString(length) + " is not a supported cipher block size");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)
|
||||
{
|
||||
BlockCipher &cipher = AccessCipher();
|
||||
unsigned int blockSize = cipher.BlockSize();
|
||||
|
||||
cipher.SetKey(key, length, params);
|
||||
m_reg.CleanNew(3*blockSize);
|
||||
m_counter = 0;
|
||||
|
||||
cipher.ProcessBlock(m_reg, m_reg+blockSize);
|
||||
MulU(m_reg+blockSize, blockSize);
|
||||
memcpy(m_reg+2*blockSize, m_reg+blockSize, blockSize);
|
||||
MulU(m_reg+2*blockSize, blockSize);
|
||||
}
|
||||
|
||||
void CMAC_Base::Update(const byte *input, size_t length)
|
||||
{
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
BlockCipher &cipher = AccessCipher();
|
||||
unsigned int blockSize = cipher.BlockSize();
|
||||
|
||||
if (m_counter > 0)
|
||||
{
|
||||
unsigned int len = UnsignedMin(blockSize - m_counter, length);
|
||||
xorbuf(m_reg+m_counter, input, len);
|
||||
length -= len;
|
||||
input += len;
|
||||
m_counter += len;
|
||||
|
||||
if (m_counter == blockSize && length > 0)
|
||||
{
|
||||
cipher.ProcessBlock(m_reg);
|
||||
m_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (length > blockSize)
|
||||
{
|
||||
assert(m_counter == 0);
|
||||
size_t leftOver = 1 + cipher.AdvancedProcessBlocks(m_reg, input, m_reg, length-1, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);
|
||||
input += (length - leftOver);
|
||||
length = leftOver;
|
||||
}
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
assert(m_counter + length <= blockSize);
|
||||
xorbuf(m_reg+m_counter, input, length);
|
||||
m_counter += (unsigned int)length;
|
||||
}
|
||||
|
||||
assert(m_counter > 0);
|
||||
}
|
||||
|
||||
void CMAC_Base::TruncatedFinal(byte *mac, size_t size)
|
||||
{
|
||||
ThrowIfInvalidTruncatedSize(size);
|
||||
|
||||
BlockCipher &cipher = AccessCipher();
|
||||
unsigned int blockSize = cipher.BlockSize();
|
||||
|
||||
if (m_counter < blockSize)
|
||||
{
|
||||
m_reg[m_counter] ^= 0x80;
|
||||
cipher.AdvancedProcessBlocks(m_reg, m_reg+2*blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);
|
||||
}
|
||||
else
|
||||
cipher.AdvancedProcessBlocks(m_reg, m_reg+blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);
|
||||
|
||||
memcpy(mac, m_reg, size);
|
||||
|
||||
m_counter = 0;
|
||||
memset(m_reg, 0, blockSize);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
104
CryptoPP/cmac.h
104
CryptoPP/cmac.h
@ -1,52 +1,52 @@
|
||||
#ifndef CRYPTOPP_CMAC_H
|
||||
#define CRYPTOPP_CMAC_H
|
||||
|
||||
#include "seckey.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! _
|
||||
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CMAC_Base : public MessageAuthenticationCode
|
||||
{
|
||||
public:
|
||||
CMAC_Base() {}
|
||||
|
||||
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms);
|
||||
void Update(const byte *input, size_t length);
|
||||
void TruncatedFinal(byte *mac, size_t size);
|
||||
unsigned int DigestSize() const {return GetCipher().BlockSize();}
|
||||
unsigned int OptimalBlockSize() const {return GetCipher().BlockSize();}
|
||||
unsigned int OptimalDataAlignment() const {return GetCipher().OptimalDataAlignment();}
|
||||
|
||||
protected:
|
||||
friend class EAX_Base;
|
||||
|
||||
const BlockCipher & GetCipher() const {return const_cast<CMAC_Base*>(this)->AccessCipher();}
|
||||
virtual BlockCipher & AccessCipher() =0;
|
||||
|
||||
void ProcessBuf();
|
||||
SecByteBlock m_reg;
|
||||
unsigned int m_counter;
|
||||
};
|
||||
|
||||
/// <a href="http://www.cryptolounge.org/wiki/CMAC">CMAC</a>
|
||||
/*! Template parameter T should be a class derived from BlockCipherDocumentation, for example AES, with a block size of 8, 16, or 32 */
|
||||
template <class T>
|
||||
class CMAC : public MessageAuthenticationCodeImpl<CMAC_Base, CMAC<T> >, public SameKeyLengthAs<T>
|
||||
{
|
||||
public:
|
||||
CMAC() {}
|
||||
CMAC(const byte *key, size_t length=SameKeyLengthAs<T>::DEFAULT_KEYLENGTH)
|
||||
{this->SetKey(key, length);}
|
||||
|
||||
static std::string StaticAlgorithmName() {return std::string("CMAC(") + T::StaticAlgorithmName() + ")";}
|
||||
|
||||
private:
|
||||
BlockCipher & AccessCipher() {return m_cipher;}
|
||||
typename T::Encryption m_cipher;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
#ifndef CRYPTOPP_CMAC_H
|
||||
#define CRYPTOPP_CMAC_H
|
||||
|
||||
#include "seckey.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! _
|
||||
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CMAC_Base : public MessageAuthenticationCode
|
||||
{
|
||||
public:
|
||||
CMAC_Base() {}
|
||||
|
||||
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms);
|
||||
void Update(const byte *input, size_t length);
|
||||
void TruncatedFinal(byte *mac, size_t size);
|
||||
unsigned int DigestSize() const {return GetCipher().BlockSize();}
|
||||
unsigned int OptimalBlockSize() const {return GetCipher().BlockSize();}
|
||||
unsigned int OptimalDataAlignment() const {return GetCipher().OptimalDataAlignment();}
|
||||
|
||||
protected:
|
||||
friend class EAX_Base;
|
||||
|
||||
const BlockCipher & GetCipher() const {return const_cast<CMAC_Base*>(this)->AccessCipher();}
|
||||
virtual BlockCipher & AccessCipher() =0;
|
||||
|
||||
void ProcessBuf();
|
||||
SecByteBlock m_reg;
|
||||
unsigned int m_counter;
|
||||
};
|
||||
|
||||
/// <a href="http://www.cryptolounge.org/wiki/CMAC">CMAC</a>
|
||||
/*! Template parameter T should be a class derived from BlockCipherDocumentation, for example AES, with a block size of 8, 16, or 32 */
|
||||
template <class T>
|
||||
class CMAC : public MessageAuthenticationCodeImpl<CMAC_Base, CMAC<T> >, public SameKeyLengthAs<T>
|
||||
{
|
||||
public:
|
||||
CMAC() {}
|
||||
CMAC(const byte *key, size_t length=SameKeyLengthAs<T>::DEFAULT_KEYLENGTH)
|
||||
{this->SetKey(key, length);}
|
||||
|
||||
static std::string StaticAlgorithmName() {return std::string("CMAC(") + T::StaticAlgorithmName() + ")";}
|
||||
|
||||
private:
|
||||
BlockCipher & AccessCipher() {return m_cipher;}
|
||||
typename T::Encryption m_cipher;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
118
CryptoPP/eax.cpp
118
CryptoPP/eax.cpp
@ -1,59 +1,59 @@
|
||||
// eax.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "eax.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void EAX_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms)
|
||||
{
|
||||
AccessMAC().SetKey(userKey, keylength, params);
|
||||
m_buffer.New(2*AccessMAC().TagSize());
|
||||
}
|
||||
|
||||
void EAX_Base::Resync(const byte *iv, size_t len)
|
||||
{
|
||||
MessageAuthenticationCode &mac = AccessMAC();
|
||||
unsigned int blockSize = mac.TagSize();
|
||||
|
||||
memset(m_buffer, 0, blockSize);
|
||||
mac.Update(m_buffer, blockSize);
|
||||
mac.CalculateDigest(m_buffer+blockSize, iv, len);
|
||||
|
||||
m_buffer[blockSize-1] = 1;
|
||||
mac.Update(m_buffer, blockSize);
|
||||
|
||||
m_ctr.SetCipherWithIV(AccessMAC().AccessCipher(), m_buffer+blockSize, blockSize);
|
||||
}
|
||||
|
||||
size_t EAX_Base::AuthenticateBlocks(const byte *data, size_t len)
|
||||
{
|
||||
AccessMAC().Update(data, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EAX_Base::AuthenticateLastHeaderBlock()
|
||||
{
|
||||
assert(m_bufferedDataLength == 0);
|
||||
MessageAuthenticationCode &mac = AccessMAC();
|
||||
unsigned int blockSize = mac.TagSize();
|
||||
|
||||
mac.Final(m_buffer);
|
||||
xorbuf(m_buffer+blockSize, m_buffer, blockSize);
|
||||
|
||||
memset(m_buffer, 0, blockSize);
|
||||
m_buffer[blockSize-1] = 2;
|
||||
mac.Update(m_buffer, blockSize);
|
||||
}
|
||||
|
||||
void EAX_Base::AuthenticateLastFooterBlock(byte *tag, size_t macSize)
|
||||
{
|
||||
assert(m_bufferedDataLength == 0);
|
||||
MessageAuthenticationCode &mac = AccessMAC();
|
||||
unsigned int blockSize = mac.TagSize();
|
||||
|
||||
mac.TruncatedFinal(m_buffer, macSize);
|
||||
xorbuf(tag, m_buffer, m_buffer+blockSize, macSize);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
// eax.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "eax.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void EAX_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms)
|
||||
{
|
||||
AccessMAC().SetKey(userKey, keylength, params);
|
||||
m_buffer.New(2*AccessMAC().TagSize());
|
||||
}
|
||||
|
||||
void EAX_Base::Resync(const byte *iv, size_t len)
|
||||
{
|
||||
MessageAuthenticationCode &mac = AccessMAC();
|
||||
unsigned int blockSize = mac.TagSize();
|
||||
|
||||
memset(m_buffer, 0, blockSize);
|
||||
mac.Update(m_buffer, blockSize);
|
||||
mac.CalculateDigest(m_buffer+blockSize, iv, len);
|
||||
|
||||
m_buffer[blockSize-1] = 1;
|
||||
mac.Update(m_buffer, blockSize);
|
||||
|
||||
m_ctr.SetCipherWithIV(AccessMAC().AccessCipher(), m_buffer+blockSize, blockSize);
|
||||
}
|
||||
|
||||
size_t EAX_Base::AuthenticateBlocks(const byte *data, size_t len)
|
||||
{
|
||||
AccessMAC().Update(data, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EAX_Base::AuthenticateLastHeaderBlock()
|
||||
{
|
||||
assert(m_bufferedDataLength == 0);
|
||||
MessageAuthenticationCode &mac = AccessMAC();
|
||||
unsigned int blockSize = mac.TagSize();
|
||||
|
||||
mac.Final(m_buffer);
|
||||
xorbuf(m_buffer+blockSize, m_buffer, blockSize);
|
||||
|
||||
memset(m_buffer, 0, blockSize);
|
||||
m_buffer[blockSize-1] = 2;
|
||||
mac.Update(m_buffer, blockSize);
|
||||
}
|
||||
|
||||
void EAX_Base::AuthenticateLastFooterBlock(byte *tag, size_t macSize)
|
||||
{
|
||||
assert(m_bufferedDataLength == 0);
|
||||
MessageAuthenticationCode &mac = AccessMAC();
|
||||
unsigned int blockSize = mac.TagSize();
|
||||
|
||||
mac.TruncatedFinal(m_buffer, macSize);
|
||||
xorbuf(tag, m_buffer, m_buffer+blockSize, macSize);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
1656
CryptoPP/gcm.cpp
1656
CryptoPP/gcm.cpp
File diff suppressed because it is too large
Load Diff
212
CryptoPP/gcm.h
212
CryptoPP/gcm.h
@ -1,106 +1,106 @@
|
||||
#ifndef CRYPTOPP_GCM_H
|
||||
#define CRYPTOPP_GCM_H
|
||||
|
||||
#include "authenc.h"
|
||||
#include "modes.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! .
|
||||
enum GCM_TablesOption {GCM_2K_Tables, GCM_64K_Tables};
|
||||
|
||||
//! .
|
||||
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase
|
||||
{
|
||||
public:
|
||||
// AuthenticatedSymmetricCipher
|
||||
std::string AlgorithmName() const
|
||||
{return GetBlockCipher().AlgorithmName() + std::string("/GCM");}
|
||||
size_t MinKeyLength() const
|
||||
{return GetBlockCipher().MinKeyLength();}
|
||||
size_t MaxKeyLength() const
|
||||
{return GetBlockCipher().MaxKeyLength();}
|
||||
size_t DefaultKeyLength() const
|
||||
{return GetBlockCipher().DefaultKeyLength();}
|
||||
size_t GetValidKeyLength(size_t n) const
|
||||
{return GetBlockCipher().GetValidKeyLength(n);}
|
||||
bool IsValidKeyLength(size_t n) const
|
||||
{return GetBlockCipher().IsValidKeyLength(n);}
|
||||
unsigned int OptimalDataAlignment() const;
|
||||
IV_Requirement IVRequirement() const
|
||||
{return UNIQUE_IV;}
|
||||
unsigned int IVSize() const
|
||||
{return 12;}
|
||||
unsigned int MinIVLength() const
|
||||
{return 1;}
|
||||
unsigned int MaxIVLength() const
|
||||
{return UINT_MAX;} // (W64LIT(1)<<61)-1 in the standard
|
||||
unsigned int DigestSize() const
|
||||
{return 16;}
|
||||
lword MaxHeaderLength() const
|
||||
{return (W64LIT(1)<<61)-1;}
|
||||
lword MaxMessageLength() const
|
||||
{return ((W64LIT(1)<<39)-256)/8;}
|
||||
|
||||
protected:
|
||||
// AuthenticatedSymmetricCipherBase
|
||||
bool AuthenticationIsOnPlaintext() const
|
||||
{return false;}
|
||||
unsigned int AuthenticationBlockSize() const
|
||||
{return HASH_BLOCKSIZE;}
|
||||
void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms);
|
||||
void Resync(const byte *iv, size_t len);
|
||||
size_t AuthenticateBlocks(const byte *data, size_t len);
|
||||
void AuthenticateLastHeaderBlock();
|
||||
void AuthenticateLastConfidentialBlock();
|
||||
void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
|
||||
SymmetricCipher & AccessSymmetricCipher() {return m_ctr;}
|
||||
|
||||
virtual BlockCipher & AccessBlockCipher() =0;
|
||||
virtual GCM_TablesOption GetTablesOption() const =0;
|
||||
|
||||
const BlockCipher & GetBlockCipher() const {return const_cast<GCM_Base *>(this)->AccessBlockCipher();};
|
||||
byte *HashBuffer() {return m_buffer+REQUIRED_BLOCKSIZE;}
|
||||
byte *HashKey() {return m_buffer+2*REQUIRED_BLOCKSIZE;}
|
||||
byte *MulTable() {return m_buffer+3*REQUIRED_BLOCKSIZE;}
|
||||
inline void ReverseHashBufferIfNeeded();
|
||||
|
||||
class CRYPTOPP_DLL GCTR : public CTR_Mode_ExternalCipher::Encryption
|
||||
{
|
||||
protected:
|
||||
void IncrementCounterBy256();
|
||||
};
|
||||
|
||||
GCTR m_ctr;
|
||||
static word16 s_reductionTable[256];
|
||||
static volatile bool s_reductionTableInitialized;
|
||||
enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16};
|
||||
};
|
||||
|
||||
//! .
|
||||
template <class T_BlockCipher, GCM_TablesOption T_TablesOption, bool T_IsEncryption>
|
||||
class GCM_Final : public GCM_Base
|
||||
{
|
||||
public:
|
||||
static std::string StaticAlgorithmName()
|
||||
{return T_BlockCipher::StaticAlgorithmName() + std::string("/GCM");}
|
||||
bool IsForwardTransformation() const
|
||||
{return T_IsEncryption;}
|
||||
|
||||
private:
|
||||
GCM_TablesOption GetTablesOption() const {return T_TablesOption;}
|
||||
BlockCipher & AccessBlockCipher() {return m_cipher;}
|
||||
typename T_BlockCipher::Encryption m_cipher;
|
||||
};
|
||||
|
||||
//! <a href="http://www.cryptolounge.org/wiki/GCM">GCM</a>
|
||||
template <class T_BlockCipher, GCM_TablesOption T_TablesOption=GCM_2K_Tables>
|
||||
struct GCM : public AuthenticatedSymmetricCipherDocumentation
|
||||
{
|
||||
typedef GCM_Final<T_BlockCipher, T_TablesOption, true> Encryption;
|
||||
typedef GCM_Final<T_BlockCipher, T_TablesOption, false> Decryption;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
#ifndef CRYPTOPP_GCM_H
|
||||
#define CRYPTOPP_GCM_H
|
||||
|
||||
#include "authenc.h"
|
||||
#include "modes.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! .
|
||||
enum GCM_TablesOption {GCM_2K_Tables, GCM_64K_Tables};
|
||||
|
||||
//! .
|
||||
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase
|
||||
{
|
||||
public:
|
||||
// AuthenticatedSymmetricCipher
|
||||
std::string AlgorithmName() const
|
||||
{return GetBlockCipher().AlgorithmName() + std::string("/GCM");}
|
||||
size_t MinKeyLength() const
|
||||
{return GetBlockCipher().MinKeyLength();}
|
||||
size_t MaxKeyLength() const
|
||||
{return GetBlockCipher().MaxKeyLength();}
|
||||
size_t DefaultKeyLength() const
|
||||
{return GetBlockCipher().DefaultKeyLength();}
|
||||
size_t GetValidKeyLength(size_t n) const
|
||||
{return GetBlockCipher().GetValidKeyLength(n);}
|
||||
bool IsValidKeyLength(size_t n) const
|
||||
{return GetBlockCipher().IsValidKeyLength(n);}
|
||||
unsigned int OptimalDataAlignment() const;
|
||||
IV_Requirement IVRequirement() const
|
||||
{return UNIQUE_IV;}
|
||||
unsigned int IVSize() const
|
||||
{return 12;}
|
||||
unsigned int MinIVLength() const
|
||||
{return 1;}
|
||||
unsigned int MaxIVLength() const
|
||||
{return UINT_MAX;} // (W64LIT(1)<<61)-1 in the standard
|
||||
unsigned int DigestSize() const
|
||||
{return 16;}
|
||||
lword MaxHeaderLength() const
|
||||
{return (W64LIT(1)<<61)-1;}
|
||||
lword MaxMessageLength() const
|
||||
{return ((W64LIT(1)<<39)-256)/8;}
|
||||
|
||||
protected:
|
||||
// AuthenticatedSymmetricCipherBase
|
||||
bool AuthenticationIsOnPlaintext() const
|
||||
{return false;}
|
||||
unsigned int AuthenticationBlockSize() const
|
||||
{return HASH_BLOCKSIZE;}
|
||||
void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms);
|
||||
void Resync(const byte *iv, size_t len);
|
||||
size_t AuthenticateBlocks(const byte *data, size_t len);
|
||||
void AuthenticateLastHeaderBlock();
|
||||
void AuthenticateLastConfidentialBlock();
|
||||
void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
|
||||
SymmetricCipher & AccessSymmetricCipher() {return m_ctr;}
|
||||
|
||||
virtual BlockCipher & AccessBlockCipher() =0;
|
||||
virtual GCM_TablesOption GetTablesOption() const =0;
|
||||
|
||||
const BlockCipher & GetBlockCipher() const {return const_cast<GCM_Base *>(this)->AccessBlockCipher();};
|
||||
byte *HashBuffer() {return m_buffer+REQUIRED_BLOCKSIZE;}
|
||||
byte *HashKey() {return m_buffer+2*REQUIRED_BLOCKSIZE;}
|
||||
byte *MulTable() {return m_buffer+3*REQUIRED_BLOCKSIZE;}
|
||||
inline void ReverseHashBufferIfNeeded();
|
||||
|
||||
class CRYPTOPP_DLL GCTR : public CTR_Mode_ExternalCipher::Encryption
|
||||
{
|
||||
protected:
|
||||
void IncrementCounterBy256();
|
||||
};
|
||||
|
||||
GCTR m_ctr;
|
||||
static word16 s_reductionTable[256];
|
||||
static volatile bool s_reductionTableInitialized;
|
||||
enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16};
|
||||
};
|
||||
|
||||
//! .
|
||||
template <class T_BlockCipher, GCM_TablesOption T_TablesOption, bool T_IsEncryption>
|
||||
class GCM_Final : public GCM_Base
|
||||
{
|
||||
public:
|
||||
static std::string StaticAlgorithmName()
|
||||
{return T_BlockCipher::StaticAlgorithmName() + std::string("/GCM");}
|
||||
bool IsForwardTransformation() const
|
||||
{return T_IsEncryption;}
|
||||
|
||||
private:
|
||||
GCM_TablesOption GetTablesOption() const {return T_TablesOption;}
|
||||
BlockCipher & AccessBlockCipher() {return m_cipher;}
|
||||
typename T_BlockCipher::Encryption m_cipher;
|
||||
};
|
||||
|
||||
//! <a href="http://www.cryptolounge.org/wiki/GCM">GCM</a>
|
||||
template <class T_BlockCipher, GCM_TablesOption T_TablesOption=GCM_2K_Tables>
|
||||
struct GCM : public AuthenticatedSymmetricCipherDocumentation
|
||||
{
|
||||
typedef GCM_Final<T_BlockCipher, T_TablesOption, true> Encryption;
|
||||
typedef GCM_Final<T_BlockCipher, T_TablesOption, false> Decryption;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
@ -1,104 +1,104 @@
|
||||
// seed.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "seed.h"
|
||||
#include "misc.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
static const word32 s_kc[16] = {
|
||||
0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc, 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf,
|
||||
0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1, 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b};
|
||||
|
||||
static const byte s_s0[256] = {
|
||||
0xA9, 0x85, 0xD6, 0xD3, 0x54, 0x1D, 0xAC, 0x25, 0x5D, 0x43, 0x18, 0x1E, 0x51, 0xFC, 0xCA, 0x63, 0x28,
|
||||
0x44, 0x20, 0x9D, 0xE0, 0xE2, 0xC8, 0x17, 0xA5, 0x8F, 0x03, 0x7B, 0xBB, 0x13, 0xD2, 0xEE, 0x70, 0x8C,
|
||||
0x3F, 0xA8, 0x32, 0xDD, 0xF6, 0x74, 0xEC, 0x95, 0x0B, 0x57, 0x5C, 0x5B, 0xBD, 0x01, 0x24, 0x1C, 0x73,
|
||||
0x98, 0x10, 0xCC, 0xF2, 0xD9, 0x2C, 0xE7, 0x72, 0x83, 0x9B, 0xD1, 0x86, 0xC9, 0x60, 0x50, 0xA3, 0xEB,
|
||||
0x0D, 0xB6, 0x9E, 0x4F, 0xB7, 0x5A, 0xC6, 0x78, 0xA6, 0x12, 0xAF, 0xD5, 0x61, 0xC3, 0xB4, 0x41, 0x52,
|
||||
0x7D, 0x8D, 0x08, 0x1F, 0x99, 0x00, 0x19, 0x04, 0x53, 0xF7, 0xE1, 0xFD, 0x76, 0x2F, 0x27, 0xB0, 0x8B,
|
||||
0x0E, 0xAB, 0xA2, 0x6E, 0x93, 0x4D, 0x69, 0x7C, 0x09, 0x0A, 0xBF, 0xEF, 0xF3, 0xC5, 0x87, 0x14, 0xFE,
|
||||
0x64, 0xDE, 0x2E, 0x4B, 0x1A, 0x06, 0x21, 0x6B, 0x66, 0x02, 0xF5, 0x92, 0x8A, 0x0C, 0xB3, 0x7E, 0xD0,
|
||||
0x7A, 0x47, 0x96, 0xE5, 0x26, 0x80, 0xAD, 0xDF, 0xA1, 0x30, 0x37, 0xAE, 0x36, 0x15, 0x22, 0x38, 0xF4,
|
||||
0xA7, 0x45, 0x4C, 0x81, 0xE9, 0x84, 0x97, 0x35, 0xCB, 0xCE, 0x3C, 0x71, 0x11, 0xC7, 0x89, 0x75, 0xFB,
|
||||
0xDA, 0xF8, 0x94, 0x59, 0x82, 0xC4, 0xFF, 0x49, 0x39, 0x67, 0xC0, 0xCF, 0xD7, 0xB8, 0x0F, 0x8E, 0x42,
|
||||
0x23, 0x91, 0x6C, 0xDB, 0xA4, 0x34, 0xF1, 0x48, 0xC2, 0x6F, 0x3D, 0x2D, 0x40, 0xBE, 0x3E, 0xBC, 0xC1,
|
||||
0xAA, 0xBA, 0x4E, 0x55, 0x3B, 0xDC, 0x68, 0x7F, 0x9C, 0xD8, 0x4A, 0x56, 0x77, 0xA0, 0xED, 0x46, 0xB5,
|
||||
0x2B, 0x65, 0xFA, 0xE3, 0xB9, 0xB1, 0x9F, 0x5E, 0xF9, 0xE6, 0xB2, 0x31, 0xEA, 0x6D, 0x5F, 0xE4, 0xF0,
|
||||
0xCD, 0x88, 0x16, 0x3A, 0x58, 0xD4, 0x62, 0x29, 0x07, 0x33, 0xE8, 0x1B, 0x05, 0x79, 0x90, 0x6A, 0x2A,
|
||||
0x9A};
|
||||
|
||||
static const byte s_s1[256] = {
|
||||
0x38, 0xE8, 0x2D, 0xA6, 0xCF, 0xDE, 0xB3, 0xB8, 0xAF, 0x60, 0x55, 0xC7, 0x44, 0x6F, 0x6B, 0x5B, 0xC3,
|
||||
0x62, 0x33, 0xB5, 0x29, 0xA0, 0xE2, 0xA7, 0xD3, 0x91, 0x11, 0x06, 0x1C, 0xBC, 0x36, 0x4B, 0xEF, 0x88,
|
||||
0x6C, 0xA8, 0x17, 0xC4, 0x16, 0xF4, 0xC2, 0x45, 0xE1, 0xD6, 0x3F, 0x3D, 0x8E, 0x98, 0x28, 0x4E, 0xF6,
|
||||
0x3E, 0xA5, 0xF9, 0x0D, 0xDF, 0xD8, 0x2B, 0x66, 0x7A, 0x27, 0x2F, 0xF1, 0x72, 0x42, 0xD4, 0x41, 0xC0,
|
||||
0x73, 0x67, 0xAC, 0x8B, 0xF7, 0xAD, 0x80, 0x1F, 0xCA, 0x2C, 0xAA, 0x34, 0xD2, 0x0B, 0xEE, 0xE9, 0x5D,
|
||||
0x94, 0x18, 0xF8, 0x57, 0xAE, 0x08, 0xC5, 0x13, 0xCD, 0x86, 0xB9, 0xFF, 0x7D, 0xC1, 0x31, 0xF5, 0x8A,
|
||||
0x6A, 0xB1, 0xD1, 0x20, 0xD7, 0x02, 0x22, 0x04, 0x68, 0x71, 0x07, 0xDB, 0x9D, 0x99, 0x61, 0xBE, 0xE6,
|
||||
0x59, 0xDD, 0x51, 0x90, 0xDC, 0x9A, 0xA3, 0xAB, 0xD0, 0x81, 0x0F, 0x47, 0x1A, 0xE3, 0xEC, 0x8D, 0xBF,
|
||||
0x96, 0x7B, 0x5C, 0xA2, 0xA1, 0x63, 0x23, 0x4D, 0xC8, 0x9E, 0x9C, 0x3A, 0x0C, 0x2E, 0xBA, 0x6E, 0x9F,
|
||||
0x5A, 0xF2, 0x92, 0xF3, 0x49, 0x78, 0xCC, 0x15, 0xFB, 0x70, 0x75, 0x7F, 0x35, 0x10, 0x03, 0x64, 0x6D,
|
||||
0xC6, 0x74, 0xD5, 0xB4, 0xEA, 0x09, 0x76, 0x19, 0xFE, 0x40, 0x12, 0xE0, 0xBD, 0x05, 0xFA, 0x01, 0xF0,
|
||||
0x2A, 0x5E, 0xA9, 0x56, 0x43, 0x85, 0x14, 0x89, 0x9B, 0xB0, 0xE5, 0x48, 0x79, 0x97, 0xFC, 0x1E, 0x82,
|
||||
0x21, 0x8C, 0x1B, 0x5F, 0x77, 0x54, 0xB2, 0x1D, 0x25, 0x4F, 0x00, 0x46, 0xED, 0x58, 0x52, 0xEB, 0x7E,
|
||||
0xDA, 0xC9, 0xFD, 0x30, 0x95, 0x65, 0x3C, 0xB6, 0xE4, 0xBB, 0x7C, 0x0E, 0x50, 0x39, 0x26, 0x32, 0x84,
|
||||
0x69, 0x93, 0x37, 0xE7, 0x24, 0xA4, 0xCB, 0x53, 0x0A, 0x87, 0xD9, 0x4C, 0x83, 0x8F, 0xCE, 0x3B, 0x4A,
|
||||
0xB7};
|
||||
|
||||
#define SS0(x) ((s_s0[x]*0x01010101UL) & 0x3FCFF3FC)
|
||||
#define SS1(x) ((s_s1[x]*0x01010101UL) & 0xFC3FCFF3)
|
||||
#define SS2(x) ((s_s0[x]*0x01010101UL) & 0xF3FC3FCF)
|
||||
#define SS3(x) ((s_s1[x]*0x01010101UL) & 0xCFF3FC3F)
|
||||
#define G(x) (SS0(GETBYTE(x, 0)) ^ SS1(GETBYTE(x, 1)) ^ SS2(GETBYTE(x, 2)) ^ SS3(GETBYTE(x, 3)))
|
||||
|
||||
void SEED::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms)
|
||||
{
|
||||
AssertValidKeyLength(length);
|
||||
|
||||
word64 key01, key23;
|
||||
GetBlock<word64, BigEndian> get(userKey);
|
||||
get(key01)(key23);
|
||||
word32 *k = m_k;
|
||||
size_t kInc = 2;
|
||||
if (!IsForwardTransformation())
|
||||
{
|
||||
k = k+30;
|
||||
kInc = 0-kInc;
|
||||
}
|
||||
|
||||
for (int i=0; i<ROUNDS; i++)
|
||||
{
|
||||
word32 t0 = word32(key01>>32) + word32(key23>>32) - s_kc[i];
|
||||
word32 t1 = word32(key01) - word32(key23) + s_kc[i];
|
||||
k[0] = G(t0);
|
||||
k[1] = G(t1);
|
||||
k+=kInc;
|
||||
if (i&1)
|
||||
key23 = rotlFixed<word64>(key23, 8);
|
||||
else
|
||||
key01 = rotrFixed<word64>(key01, 8);
|
||||
}
|
||||
}
|
||||
|
||||
void SEED::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
typedef BlockGetAndPut<word32, BigEndian> Block;
|
||||
word32 a0, a1, b0, b1, t0, t1;
|
||||
Block::Get(inBlock)(a0)(a1)(b0)(b1);
|
||||
|
||||
for (int i=0; i<ROUNDS; i+=2)
|
||||
{
|
||||
t0 = b0 ^ m_k[2*i+0]; t1 = b1 ^ m_k[2*i+1] ^ t0;
|
||||
t1 = G(t1); t0 += t1; t0 = G(t0); t1 += t0; t1 = G(t1);
|
||||
a0 ^= t0 + t1; a1 ^= t1;
|
||||
|
||||
t0 = a0 ^ m_k[2*i+2]; t1 = a1 ^ m_k[2*i+3] ^ t0;
|
||||
t1 = G(t1); t0 += t1; t0 = G(t0); t1 += t0; t1 = G(t1);
|
||||
b0 ^= t0 + t1; b1 ^= t1;
|
||||
}
|
||||
|
||||
Block::Put(xorBlock, outBlock)(b0)(b1)(a0)(a1);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
// seed.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "seed.h"
|
||||
#include "misc.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
static const word32 s_kc[16] = {
|
||||
0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc, 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf,
|
||||
0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1, 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b};
|
||||
|
||||
static const byte s_s0[256] = {
|
||||
0xA9, 0x85, 0xD6, 0xD3, 0x54, 0x1D, 0xAC, 0x25, 0x5D, 0x43, 0x18, 0x1E, 0x51, 0xFC, 0xCA, 0x63, 0x28,
|
||||
0x44, 0x20, 0x9D, 0xE0, 0xE2, 0xC8, 0x17, 0xA5, 0x8F, 0x03, 0x7B, 0xBB, 0x13, 0xD2, 0xEE, 0x70, 0x8C,
|
||||
0x3F, 0xA8, 0x32, 0xDD, 0xF6, 0x74, 0xEC, 0x95, 0x0B, 0x57, 0x5C, 0x5B, 0xBD, 0x01, 0x24, 0x1C, 0x73,
|
||||
0x98, 0x10, 0xCC, 0xF2, 0xD9, 0x2C, 0xE7, 0x72, 0x83, 0x9B, 0xD1, 0x86, 0xC9, 0x60, 0x50, 0xA3, 0xEB,
|
||||
0x0D, 0xB6, 0x9E, 0x4F, 0xB7, 0x5A, 0xC6, 0x78, 0xA6, 0x12, 0xAF, 0xD5, 0x61, 0xC3, 0xB4, 0x41, 0x52,
|
||||
0x7D, 0x8D, 0x08, 0x1F, 0x99, 0x00, 0x19, 0x04, 0x53, 0xF7, 0xE1, 0xFD, 0x76, 0x2F, 0x27, 0xB0, 0x8B,
|
||||
0x0E, 0xAB, 0xA2, 0x6E, 0x93, 0x4D, 0x69, 0x7C, 0x09, 0x0A, 0xBF, 0xEF, 0xF3, 0xC5, 0x87, 0x14, 0xFE,
|
||||
0x64, 0xDE, 0x2E, 0x4B, 0x1A, 0x06, 0x21, 0x6B, 0x66, 0x02, 0xF5, 0x92, 0x8A, 0x0C, 0xB3, 0x7E, 0xD0,
|
||||
0x7A, 0x47, 0x96, 0xE5, 0x26, 0x80, 0xAD, 0xDF, 0xA1, 0x30, 0x37, 0xAE, 0x36, 0x15, 0x22, 0x38, 0xF4,
|
||||
0xA7, 0x45, 0x4C, 0x81, 0xE9, 0x84, 0x97, 0x35, 0xCB, 0xCE, 0x3C, 0x71, 0x11, 0xC7, 0x89, 0x75, 0xFB,
|
||||
0xDA, 0xF8, 0x94, 0x59, 0x82, 0xC4, 0xFF, 0x49, 0x39, 0x67, 0xC0, 0xCF, 0xD7, 0xB8, 0x0F, 0x8E, 0x42,
|
||||
0x23, 0x91, 0x6C, 0xDB, 0xA4, 0x34, 0xF1, 0x48, 0xC2, 0x6F, 0x3D, 0x2D, 0x40, 0xBE, 0x3E, 0xBC, 0xC1,
|
||||
0xAA, 0xBA, 0x4E, 0x55, 0x3B, 0xDC, 0x68, 0x7F, 0x9C, 0xD8, 0x4A, 0x56, 0x77, 0xA0, 0xED, 0x46, 0xB5,
|
||||
0x2B, 0x65, 0xFA, 0xE3, 0xB9, 0xB1, 0x9F, 0x5E, 0xF9, 0xE6, 0xB2, 0x31, 0xEA, 0x6D, 0x5F, 0xE4, 0xF0,
|
||||
0xCD, 0x88, 0x16, 0x3A, 0x58, 0xD4, 0x62, 0x29, 0x07, 0x33, 0xE8, 0x1B, 0x05, 0x79, 0x90, 0x6A, 0x2A,
|
||||
0x9A};
|
||||
|
||||
static const byte s_s1[256] = {
|
||||
0x38, 0xE8, 0x2D, 0xA6, 0xCF, 0xDE, 0xB3, 0xB8, 0xAF, 0x60, 0x55, 0xC7, 0x44, 0x6F, 0x6B, 0x5B, 0xC3,
|
||||
0x62, 0x33, 0xB5, 0x29, 0xA0, 0xE2, 0xA7, 0xD3, 0x91, 0x11, 0x06, 0x1C, 0xBC, 0x36, 0x4B, 0xEF, 0x88,
|
||||
0x6C, 0xA8, 0x17, 0xC4, 0x16, 0xF4, 0xC2, 0x45, 0xE1, 0xD6, 0x3F, 0x3D, 0x8E, 0x98, 0x28, 0x4E, 0xF6,
|
||||
0x3E, 0xA5, 0xF9, 0x0D, 0xDF, 0xD8, 0x2B, 0x66, 0x7A, 0x27, 0x2F, 0xF1, 0x72, 0x42, 0xD4, 0x41, 0xC0,
|
||||
0x73, 0x67, 0xAC, 0x8B, 0xF7, 0xAD, 0x80, 0x1F, 0xCA, 0x2C, 0xAA, 0x34, 0xD2, 0x0B, 0xEE, 0xE9, 0x5D,
|
||||
0x94, 0x18, 0xF8, 0x57, 0xAE, 0x08, 0xC5, 0x13, 0xCD, 0x86, 0xB9, 0xFF, 0x7D, 0xC1, 0x31, 0xF5, 0x8A,
|
||||
0x6A, 0xB1, 0xD1, 0x20, 0xD7, 0x02, 0x22, 0x04, 0x68, 0x71, 0x07, 0xDB, 0x9D, 0x99, 0x61, 0xBE, 0xE6,
|
||||
0x59, 0xDD, 0x51, 0x90, 0xDC, 0x9A, 0xA3, 0xAB, 0xD0, 0x81, 0x0F, 0x47, 0x1A, 0xE3, 0xEC, 0x8D, 0xBF,
|
||||
0x96, 0x7B, 0x5C, 0xA2, 0xA1, 0x63, 0x23, 0x4D, 0xC8, 0x9E, 0x9C, 0x3A, 0x0C, 0x2E, 0xBA, 0x6E, 0x9F,
|
||||
0x5A, 0xF2, 0x92, 0xF3, 0x49, 0x78, 0xCC, 0x15, 0xFB, 0x70, 0x75, 0x7F, 0x35, 0x10, 0x03, 0x64, 0x6D,
|
||||
0xC6, 0x74, 0xD5, 0xB4, 0xEA, 0x09, 0x76, 0x19, 0xFE, 0x40, 0x12, 0xE0, 0xBD, 0x05, 0xFA, 0x01, 0xF0,
|
||||
0x2A, 0x5E, 0xA9, 0x56, 0x43, 0x85, 0x14, 0x89, 0x9B, 0xB0, 0xE5, 0x48, 0x79, 0x97, 0xFC, 0x1E, 0x82,
|
||||
0x21, 0x8C, 0x1B, 0x5F, 0x77, 0x54, 0xB2, 0x1D, 0x25, 0x4F, 0x00, 0x46, 0xED, 0x58, 0x52, 0xEB, 0x7E,
|
||||
0xDA, 0xC9, 0xFD, 0x30, 0x95, 0x65, 0x3C, 0xB6, 0xE4, 0xBB, 0x7C, 0x0E, 0x50, 0x39, 0x26, 0x32, 0x84,
|
||||
0x69, 0x93, 0x37, 0xE7, 0x24, 0xA4, 0xCB, 0x53, 0x0A, 0x87, 0xD9, 0x4C, 0x83, 0x8F, 0xCE, 0x3B, 0x4A,
|
||||
0xB7};
|
||||
|
||||
#define SS0(x) ((s_s0[x]*0x01010101UL) & 0x3FCFF3FC)
|
||||
#define SS1(x) ((s_s1[x]*0x01010101UL) & 0xFC3FCFF3)
|
||||
#define SS2(x) ((s_s0[x]*0x01010101UL) & 0xF3FC3FCF)
|
||||
#define SS3(x) ((s_s1[x]*0x01010101UL) & 0xCFF3FC3F)
|
||||
#define G(x) (SS0(GETBYTE(x, 0)) ^ SS1(GETBYTE(x, 1)) ^ SS2(GETBYTE(x, 2)) ^ SS3(GETBYTE(x, 3)))
|
||||
|
||||
void SEED::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms)
|
||||
{
|
||||
AssertValidKeyLength(length);
|
||||
|
||||
word64 key01, key23;
|
||||
GetBlock<word64, BigEndian> get(userKey);
|
||||
get(key01)(key23);
|
||||
word32 *k = m_k;
|
||||
size_t kInc = 2;
|
||||
if (!IsForwardTransformation())
|
||||
{
|
||||
k = k+30;
|
||||
kInc = 0-kInc;
|
||||
}
|
||||
|
||||
for (int i=0; i<ROUNDS; i++)
|
||||
{
|
||||
word32 t0 = word32(key01>>32) + word32(key23>>32) - s_kc[i];
|
||||
word32 t1 = word32(key01) - word32(key23) + s_kc[i];
|
||||
k[0] = G(t0);
|
||||
k[1] = G(t1);
|
||||
k+=kInc;
|
||||
if (i&1)
|
||||
key23 = rotlFixed<word64>(key23, 8);
|
||||
else
|
||||
key01 = rotrFixed<word64>(key01, 8);
|
||||
}
|
||||
}
|
||||
|
||||
void SEED::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
typedef BlockGetAndPut<word32, BigEndian> Block;
|
||||
word32 a0, a1, b0, b1, t0, t1;
|
||||
Block::Get(inBlock)(a0)(a1)(b0)(b1);
|
||||
|
||||
for (int i=0; i<ROUNDS; i+=2)
|
||||
{
|
||||
t0 = b0 ^ m_k[2*i+0]; t1 = b1 ^ m_k[2*i+1] ^ t0;
|
||||
t1 = G(t1); t0 += t1; t0 = G(t0); t1 += t0; t1 = G(t1);
|
||||
a0 ^= t0 + t1; a1 ^= t1;
|
||||
|
||||
t0 = a0 ^ m_k[2*i+2]; t1 = a1 ^ m_k[2*i+3] ^ t0;
|
||||
t1 = G(t1); t0 += t1; t0 = G(t0); t1 += t0; t1 = G(t1);
|
||||
b0 ^= t0 + t1; b1 ^= t1;
|
||||
}
|
||||
|
||||
Block::Put(xorBlock, outBlock)(b0)(b1)(a0)(a1);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
@ -1,21 +1,21 @@
|
||||
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
@ -1,27 +1,27 @@
|
||||
/************************************************************************
|
||||
* lsqlite3 *
|
||||
* Copyright (C) 2002-2013 Tiago Dionizio, Doug Currie *
|
||||
* All rights reserved. *
|
||||
* Author : Tiago Dionizio <tiago.dionizio@ist.utl.pt> *
|
||||
* Author : Doug Currie <doug.currie@alum.mit.edu> *
|
||||
* Library : lsqlite3 - a SQLite 3 database binding for Lua 5 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining *
|
||||
* a copy of this software and associated documentation files (the *
|
||||
* "Software"), to deal in the Software without restriction, including *
|
||||
* without limitation the rights to use, copy, modify, merge, publish, *
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to *
|
||||
* the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be *
|
||||
* included in all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY *
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, *
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE *
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
************************************************************************/
|
||||
/************************************************************************
|
||||
* lsqlite3 *
|
||||
* Copyright (C) 2002-2013 Tiago Dionizio, Doug Currie *
|
||||
* All rights reserved. *
|
||||
* Author : Tiago Dionizio <tiago.dionizio@ist.utl.pt> *
|
||||
* Author : Doug Currie <doug.currie@alum.mit.edu> *
|
||||
* Library : lsqlite3 - a SQLite 3 database binding for Lua 5 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining *
|
||||
* a copy of this software and associated documentation files (the *
|
||||
* "Software"), to deal in the Software without restriction, including *
|
||||
* without limitation the rights to use, copy, modify, merge, publish, *
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to *
|
||||
* the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be *
|
||||
* included in all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY *
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, *
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE *
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
************************************************************************/
|
||||
|
@ -1,43 +1,43 @@
|
||||
// The Mersenne Twister is an algorithm for generating random numbers. It
|
||||
// was designed with consideration of the flaws in various other generators.
|
||||
// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
|
||||
// are far greater. The generator is also fast; it avoids multiplication and
|
||||
// division, and it benefits from caches and pipelines. For more information
|
||||
// see the inventors' web page at
|
||||
// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
||||
|
||||
// Reference
|
||||
// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
|
||||
// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
|
||||
// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
|
||||
|
||||
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
// Copyright (C) 2000 - 2009, Richard J. Wagner
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. The names of its contributors may not be used to endorse or promote
|
||||
// products derived from this software without specific prior written
|
||||
// permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// The Mersenne Twister is an algorithm for generating random numbers. It
|
||||
// was designed with consideration of the flaws in various other generators.
|
||||
// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
|
||||
// are far greater. The generator is also fast; it avoids multiplication and
|
||||
// division, and it benefits from caches and pipelines. For more information
|
||||
// see the inventors' web page at
|
||||
// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
||||
|
||||
// Reference
|
||||
// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
|
||||
// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
|
||||
// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
|
||||
|
||||
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
// Copyright (C) 2000 - 2009, Richard J. Wagner
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. The names of its contributors may not be used to endorse or promote
|
||||
// products derived from this software without specific prior written
|
||||
// permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
@ -1,18 +1,18 @@
|
||||
..\MCServer\MCServer.exe
|
||||
..\MCServer\Plugins
|
||||
..\MCServer\webadmin
|
||||
..\MCServer\crafting.txt
|
||||
..\MCServer\furnace.txt
|
||||
..\MCServer\items.ini
|
||||
..\MCServer\monsters.ini
|
||||
MCServer*debug.cmd
|
||||
banned.example.ini
|
||||
groups.example.ini
|
||||
Lua-LICENSE.txt
|
||||
LuaExpat-license.html
|
||||
LuaSQLite3-LICENSE.txt
|
||||
MersenneTwister-LICENSE.txt
|
||||
settings.example.ini
|
||||
users.example.ini
|
||||
webadmin.example.ini
|
||||
..\MCServer\MCServer.exe
|
||||
..\MCServer\Plugins
|
||||
..\MCServer\webadmin
|
||||
..\MCServer\crafting.txt
|
||||
..\MCServer\furnace.txt
|
||||
..\MCServer\items.ini
|
||||
..\MCServer\monsters.ini
|
||||
MCServer*debug.cmd
|
||||
banned.example.ini
|
||||
groups.example.ini
|
||||
Lua-LICENSE.txt
|
||||
LuaExpat-license.html
|
||||
LuaSQLite3-LICENSE.txt
|
||||
MersenneTwister-LICENSE.txt
|
||||
settings.example.ini
|
||||
users.example.ini
|
||||
webadmin.example.ini
|
||||
whitelist.example.ini
|
@ -1,8 +1,8 @@
|
||||
MCServer\*.pdb
|
||||
VC2008\Release\*.pdb
|
||||
VC2008\Release\JsonCpp\*.pdb
|
||||
VC2008\Release\Lua\*.pdb
|
||||
VC2008\Release\ToLua\*.pdb
|
||||
VC2008\Release\webserver\*.pdb
|
||||
VC2008\Release\zlib\*.pdb
|
||||
MCServer\*.pdb
|
||||
VC2008\Release\*.pdb
|
||||
VC2008\Release\JsonCpp\*.pdb
|
||||
VC2008\Release\Lua\*.pdb
|
||||
VC2008\Release\ToLua\*.pdb
|
||||
VC2008\Release\webserver\*.pdb
|
||||
VC2008\Release\zlib\*.pdb
|
||||
source\Bindings.*
|
@ -1,3 +1,3 @@
|
||||
[Banned]
|
||||
;PlayerName=1
|
||||
|
||||
[Banned]
|
||||
;PlayerName=1
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
[Admins]
|
||||
Permissions=*
|
||||
Color=c
|
||||
|
||||
[Mods]
|
||||
Color=5
|
||||
Inherits=Vips
|
||||
Permissions=core.time,core.item
|
||||
|
||||
[Vips]
|
||||
Permissions=core.teleport
|
||||
Color=2
|
||||
Inherits=Default
|
||||
|
||||
[Default]
|
||||
Permissions=core.build,core.help,core.playerlist,core.pluginlist,core.spawn
|
||||
[Admins]
|
||||
Permissions=*
|
||||
Color=c
|
||||
|
||||
[Mods]
|
||||
Color=5
|
||||
Inherits=Vips
|
||||
Permissions=core.time,core.item
|
||||
|
||||
[Vips]
|
||||
Permissions=core.teleport
|
||||
Color=2
|
||||
Inherits=Default
|
||||
|
||||
[Default]
|
||||
Permissions=core.build,core.help,core.playerlist,core.pluginlist,core.spawn
|
||||
Color=7
|
@ -1,31 +1,31 @@
|
||||
[Server]
|
||||
Port=25565
|
||||
MaxPlayers=42
|
||||
Description=MCServer - Slightly more custom!
|
||||
|
||||
[Worlds]
|
||||
DefaultWorld=world
|
||||
;World=world_sexy
|
||||
|
||||
[Plugins]
|
||||
NewPlugin=Core
|
||||
NewPlugin=ChatLog
|
||||
|
||||
[HelpPlugin]
|
||||
ShowPluginNames=1
|
||||
|
||||
[Physics]
|
||||
Water=0
|
||||
|
||||
[Redstone]
|
||||
SimulateRedstone=0
|
||||
|
||||
[Monsters]
|
||||
AnimalsOn=0
|
||||
AnimalSpawnInterval=10
|
||||
Types=Spider,Chicken,Cow,Pig,Sheep,Squid,Enderman,Zombiepigman,Cavespider,Creeper,Ghast,Silverfish,Skeleton,Slime,Spider,Zombie
|
||||
|
||||
[Authentication]
|
||||
Server=session.minecraft.net
|
||||
Address=/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%
|
||||
Authenticate=0
|
||||
[Server]
|
||||
Port=25565
|
||||
MaxPlayers=42
|
||||
Description=MCServer - Slightly more custom!
|
||||
|
||||
[Worlds]
|
||||
DefaultWorld=world
|
||||
;World=world_sexy
|
||||
|
||||
[Plugins]
|
||||
NewPlugin=Core
|
||||
NewPlugin=ChatLog
|
||||
|
||||
[HelpPlugin]
|
||||
ShowPluginNames=1
|
||||
|
||||
[Physics]
|
||||
Water=0
|
||||
|
||||
[Redstone]
|
||||
SimulateRedstone=0
|
||||
|
||||
[Monsters]
|
||||
AnimalsOn=0
|
||||
AnimalSpawnInterval=10
|
||||
Types=Spider,Chicken,Cow,Pig,Sheep,Squid,Enderman,Zombiepigman,Cavespider,Creeper,Ghast,Silverfish,Skeleton,Slime,Spider,Zombie
|
||||
|
||||
[Authentication]
|
||||
Server=session.minecraft.net
|
||||
Address=/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%
|
||||
Authenticate=0
|
||||
|
@ -1,8 +1,8 @@
|
||||
[SomeAdmin]
|
||||
Groups=Admins
|
||||
|
||||
[FancyModerator]
|
||||
Groups=Moderators
|
||||
|
||||
[ImportantPerson]
|
||||
[SomeAdmin]
|
||||
Groups=Admins
|
||||
|
||||
[FancyModerator]
|
||||
Groups=Moderators
|
||||
|
||||
[ImportantPerson]
|
||||
Groups=Vips
|
@ -1,6 +1,6 @@
|
||||
[WebAdmin]
|
||||
Enabled=1
|
||||
Port=8080
|
||||
|
||||
[User:admin]
|
||||
[WebAdmin]
|
||||
Enabled=1
|
||||
Port=8080
|
||||
|
||||
[User:admin]
|
||||
Password=admin
|
@ -1,6 +1,6 @@
|
||||
[WhiteListSettings]
|
||||
WhiteListOn=0
|
||||
|
||||
[WhiteList]
|
||||
;PlayerName=1
|
||||
|
||||
[WhiteListSettings]
|
||||
WhiteListOn=0
|
||||
|
||||
[WhiteList]
|
||||
;PlayerName=1
|
||||
|
||||
|
@ -1,32 +1,32 @@
|
||||
|
||||
-- plugin.lua
|
||||
|
||||
-- Implements the main entrypoint for the plugin, as well as all the handling needed
|
||||
|
||||
-- ChatLog plugin logs all chat messages into the server log
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function Initialize(Plugin)
|
||||
Plugin:SetName("ChatLog")
|
||||
Plugin:SetVersion(3)
|
||||
|
||||
PluginManager = cRoot:Get():GetPluginManager()
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHAT)
|
||||
|
||||
LOG("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChat(Player, Message)
|
||||
-- Lets get loggin'
|
||||
LOGINFO("[" .. Player:GetName() .. "]: " .. StripColorCodes(Message));
|
||||
|
||||
return false
|
||||
|
||||
-- plugin.lua
|
||||
|
||||
-- Implements the main entrypoint for the plugin, as well as all the handling needed
|
||||
|
||||
-- ChatLog plugin logs all chat messages into the server log
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function Initialize(Plugin)
|
||||
Plugin:SetName("ChatLog")
|
||||
Plugin:SetVersion(3)
|
||||
|
||||
PluginManager = cRoot:Get():GetPluginManager()
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHAT)
|
||||
|
||||
LOG("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChat(Player, Message)
|
||||
-- Lets get loggin'
|
||||
LOGINFO("[" .. Player:GetName() .. "]: " .. StripColorCodes(Message));
|
||||
|
||||
return false
|
||||
end
|
@ -1,257 +1,257 @@
|
||||
local function Buttons_Player( Name )
|
||||
return "<form method='POST'><input type='hidden' name='PlayerName' value='"..Name.."'><input type='submit' name='PlayerExact' value='Exact'><input type='submit' name='Player3x3' value='3x3'></form>"
|
||||
end
|
||||
|
||||
local function Button_World( Name )
|
||||
return "<form method='POST'><input type='hidden' name='WorldName' value='"..Name.."'><input type='submit' name='SelectWorld' value='Select'></form>"
|
||||
end
|
||||
|
||||
function HandleRequest_Generation( Request )
|
||||
local Content = ""
|
||||
if (Request.PostParams["AGHRRRR"] ~= nil) then
|
||||
GENERATION_STATE = 0
|
||||
WW_instance:SaveAllChunks()
|
||||
WW_instance:UnloadUnusedChunks()
|
||||
LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works ABORTED by admin")
|
||||
end
|
||||
--Content = Content .. "<head><meta http-equiv=\"refresh\" content=\"2;\"></head>"
|
||||
-- PROCESSING
|
||||
--------------------------------------------------------------------------------------------------
|
||||
local function ProcessingContent()
|
||||
local _small_content = ""
|
||||
_small_content = _small_content .. "<head><meta http-equiv=\"refresh\" content=\"2;\"></head>"
|
||||
_small_content = _small_content .. "<h4>World for operations:</h4>"..WORK_WORLD
|
||||
if (OPERATION_CODE == 0) then
|
||||
_small_content = _small_content .. "<h4>Operation:</h4>Generation"
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
_small_content = _small_content .. "<h4>Operation:</h4>Regeneration"
|
||||
end
|
||||
_small_content = _small_content .. "<h4>Area: </h4>["..AreaStartX..":"..AreaStartZ.."] ["..AreaEndX..":"..AreaEndZ.."]"
|
||||
_small_content = _small_content .. "<h4>Progress:</h4>"..CURRENT.."/"..TOTAL
|
||||
_small_content = _small_content .. "<br>"
|
||||
_small_content = _small_content .. "<form method='POST'>"
|
||||
_small_content = _small_content .. "<input type='submit' name='AGHRRRR' value='Stop'>"
|
||||
_small_content = _small_content .. "</form>"
|
||||
return _small_content
|
||||
end
|
||||
if (GENERATION_STATE == 2 or GENERATION_STATE == 4) then
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
-- SELECTING
|
||||
--------------------------------------------------------------------------------------------------
|
||||
if ( Request.PostParams["FormSetWorld"] ) then
|
||||
WORK_WORLD = Request.PostParams["FormWorldName"]
|
||||
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
|
||||
end
|
||||
|
||||
if( Request.PostParams["SelectWorld"] ~= nil
|
||||
and Request.PostParams["WorldName"] ~= nil ) then -- World is selected!
|
||||
WORK_WORLD = Request.PostParams["WorldName"]
|
||||
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
|
||||
end
|
||||
|
||||
if(Request.PostParams["OperationGenerate"] ~= nil) then
|
||||
OPERATION_CODE = 0
|
||||
end
|
||||
if(Request.PostParams["OperationReGenerate"] ~= nil) then
|
||||
OPERATION_CODE = 1
|
||||
end
|
||||
|
||||
if (GENERATION_STATE == 0) then
|
||||
if( Request.PostParams["FormAreaStartX"] ~= nil
|
||||
and Request.PostParams["FormAreaStartZ"] ~= nil
|
||||
and Request.PostParams["FormAreaEndX"] ~= nil
|
||||
and Request.PostParams["FormAreaEndZ"] ~= nil ) then --(Re)Generation valid!
|
||||
-- COMMON (Re)gen
|
||||
if( Request.PostParams["StartArea"]) then
|
||||
AreaStartX = tonumber(Request.PostParams["FormAreaStartX"])
|
||||
AreaStartZ = tonumber(Request.PostParams["FormAreaStartZ"])
|
||||
AreaEndX = tonumber(Request.PostParams["FormAreaEndX"])
|
||||
AreaEndZ = tonumber(Request.PostParams["FormAreaEndZ"])
|
||||
|
||||
PLUGIN.IniFile:DeleteValue("Area data", "StartX")
|
||||
PLUGIN.IniFile:DeleteValue("Area data", "StartZ")
|
||||
PLUGIN.IniFile:DeleteValue("Area data", "EndX")
|
||||
PLUGIN.IniFile:DeleteValue("Area data", "EndZ")
|
||||
PLUGIN.IniFile:SetValueI("Area data", "StartX", AreaStartX)
|
||||
PLUGIN.IniFile:SetValueI("Area data", "StartZ", AreaStartZ)
|
||||
PLUGIN.IniFile:SetValueI("Area data", "EndX", AreaEndX)
|
||||
PLUGIN.IniFile:SetValueI("Area data", "EndZ", AreaEndZ)
|
||||
if (OPERATION_CODE == 0) then
|
||||
GENERATION_STATE = 1
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
GENERATION_STATE = 3
|
||||
end
|
||||
PLUGIN.IniFile:WriteFile()
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
if( Request.PostParams["FormRadialX"] ~= nil
|
||||
and Request.PostParams["FormRadialZ"] ~= nil
|
||||
and Request.PostParams["FormRadius"] ~= nil ) then --(Re)Generation valid!
|
||||
-- COMMON (Re)gen
|
||||
if( Request.PostParams["StartRadial"]) then
|
||||
RadialX = tonumber(Request.PostParams["FormRadialX"])
|
||||
RadialZ = tonumber(Request.PostParams["FormRadialZ"])
|
||||
Radius = tonumber(Request.PostParams["FormRadius"])
|
||||
AreaStartX = RadialX - Radius
|
||||
AreaStartZ = RadialZ - Radius
|
||||
AreaEndX = RadialX + Radius
|
||||
AreaEndZ = RadialZ + Radius
|
||||
|
||||
PLUGIN.IniFile:DeleteValue("Radial data", "RadialX")
|
||||
PLUGIN.IniFile:DeleteValue("Radial data", "RadialZ")
|
||||
PLUGIN.IniFile:DeleteValue("Radial data", "Radius")
|
||||
PLUGIN.IniFile:SetValueI("Radial data", "RadialX", RadialX)
|
||||
PLUGIN.IniFile:SetValueI("Radial data", "RadialZ", RadialZ)
|
||||
PLUGIN.IniFile:SetValueI("Radial data", "Radius", Radius)
|
||||
if (OPERATION_CODE == 0) then
|
||||
GENERATION_STATE = 1
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
GENERATION_STATE = 3
|
||||
end
|
||||
PLUGIN.IniFile:WriteFile()
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
-- POINT REGEN!
|
||||
if( Request.PostParams["FormPointX"] ~= nil
|
||||
and Request.PostParams["FormPointZ"] ~= nil ) then --ReGeneration valid!
|
||||
-- EXACT
|
||||
if ( Request.PostParams["PointExact"] ~= nil) then
|
||||
AreaStartX = tonumber(Request.PostParams["FormPointX"])
|
||||
AreaStartZ = tonumber(Request.PostParams["FormPointZ"])
|
||||
AreaEndX = AreaStartX
|
||||
AreaEndZ = AreaStartZ
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
-- 3x3
|
||||
if ( Request.PostParams["Point3x3"] ~= nil) then
|
||||
AreaStartX = tonumber(Request.PostParams["FormPointX"]) - 1
|
||||
AreaStartZ = tonumber(Request.PostParams["FormPointZ"]) - 1
|
||||
AreaEndX = AreaStartX + 2
|
||||
AreaEndZ = AreaStartZ + 2
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
|
||||
local GetAreaByPlayer = function(Player)
|
||||
-- Player is valid only within this function, it cannot be stord and used later!
|
||||
AreaStartX = Player:GetChunkX()
|
||||
AreaStartZ = Player:GetChunkZ()
|
||||
end
|
||||
-- PLAYERS REGEN!
|
||||
if( Request.PostParams["PlayerExact"] ~= nil
|
||||
and Request.PostParams["PlayerName"] ~= nil ) then -- Making BOOM! I meant, regenereate...
|
||||
cRoot:Get():GetWorld(WORK_WORLD):DoWithPlayer(Request.PostParams["PlayerName"],GetAreaByPlayer)
|
||||
AreaEndX = AreaStartX
|
||||
AreaEndZ = AreaStartZ
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
if( Request.PostParams["Player3x3"] ~= nil
|
||||
and Request.PostParams["PlayerName"] ~= nil ) then -- Making BOOM! I meant, regenereate...
|
||||
cRoot:Get():GetWorld(WORK_WORLD):DoWithPlayer(Request.PostParams["PlayerName"],GetAreaByPlayer)
|
||||
AreaStartX = AreaStartX - 1
|
||||
AreaStartZ = AreaStartZ - 1
|
||||
AreaEndX = AreaStartX + 2
|
||||
AreaEndZ = AreaStartZ + 2
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
|
||||
--Content = Content .. "<h4>World for operations: " .. WORK_WORLD .. "</h4>"
|
||||
--Content = Content .. "<form method='POST'>"
|
||||
--Content = Content .. "<input type='text' name='FormWorldName' value='Input world name here'><input type='submit' name='FormSetWorld' value='Set world'>"
|
||||
--Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING WORK_WORLD
|
||||
Content = Content .. "<h4>World for operations: " .. WORK_WORLD .. "</h4>"
|
||||
Content = Content .. "<table>"
|
||||
local WorldNum = 0
|
||||
local AddWorldToTable = function(World)
|
||||
WorldNum = WorldNum + 1
|
||||
Content = Content .. "<tr>"
|
||||
Content = Content .. "<td style='width: 10px;'>" .. WorldNum .. ".</td>"
|
||||
Content = Content .. "<td>" .. World:GetName() .. "</td>"
|
||||
Content = Content .. "<td>" .. Button_World(World:GetName()) .. "</td>"
|
||||
Content = Content .. "</tr>"
|
||||
end
|
||||
cRoot:Get():ForEachWorld(AddWorldToTable)
|
||||
if( WorldNum == 0 ) then
|
||||
Content = Content .. "<tr><td>No worlds! O_O</td></tr>"
|
||||
end
|
||||
Content = Content .. "</table>"
|
||||
Content = Content .. "<br>"
|
||||
|
||||
-- SELECTING OPERATION
|
||||
if (OPERATION_CODE == 0) then
|
||||
Content = Content .. "<h4>Operation: Generation</h4>"
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
Content = Content .. "<h4>Operation: Regeneration</h4>"
|
||||
end
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='submit' name='OperationGenerate' value='Generation'>"
|
||||
Content = Content .. "<input type='submit' name='OperationReGenerate' value='Regeneration'>"
|
||||
Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING AREA
|
||||
Content = Content .. "<h4>Area: </h4>Start X, Start Z; End X, End Z"
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='text' name='FormAreaStartX' value='" .. AreaStartX .. "'><input type='text' name='FormAreaStartZ' value='" .. AreaStartZ .. "'>"
|
||||
Content = Content .. "<input type='text' name='FormAreaEndX' value='" .. AreaEndX .. "'><input type='text' name='FormAreaEndZ' value='" .. AreaEndZ .. "'>"
|
||||
Content = Content .. "<input type='submit' name='StartArea' value='Start'>"
|
||||
Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING RADIAL
|
||||
Content = Content .. "<h4>Radial: </h4>Center X, Center Z, Raduis (0 to any)"
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='text' name='FormRadialX' value='" .. RadialX .. "'><input type='text' name='FormRadialZ' value='" .. RadialZ .. "'><input type='text' name='FormRadius' value='" .. Radius .. "'>"
|
||||
Content = Content .. "<input type='submit' name='StartRadial' value='Start'>"
|
||||
Content = Content .. "</form>"
|
||||
Content = Content .. "<br>"
|
||||
Content = Content .. "<br>"
|
||||
Content = Content .. "<br>"
|
||||
|
||||
-- SELECTING POINT
|
||||
Content = Content .. "<h4>Point regeneration:</h4> X, Z"
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='text' name='FormPointX' value='0'><input type='text' name='FormPointZ' value='0'>"
|
||||
Content = Content .. "<input type='submit' name='PointExact' value='Exact'>"
|
||||
Content = Content .. "<input type='submit' name='Point3x3' value='3x3'>"
|
||||
Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING PLAYERS
|
||||
Content = Content .. "<h4>Player-based regeneration:</h4>"
|
||||
Content = Content .. "<table>"
|
||||
local PlayerNum = 0
|
||||
local AddPlayerToTable = function( Player )
|
||||
PlayerNum = PlayerNum + 1
|
||||
Content = Content .. "<tr>"
|
||||
Content = Content .. "<td style='width: 10px;'>" .. PlayerNum .. ".</td>"
|
||||
Content = Content .. "<td>" .. Player:GetName() .. "</td>"
|
||||
Content = Content .. "<td>" .. Buttons_Player(Player:GetName()) .. "</td>"
|
||||
Content = Content .. "</tr>"
|
||||
end
|
||||
if (cRoot:Get():GetWorld(WORK_WORLD) == nil) then
|
||||
Content = Content .. "<tr><td>Incorrect world selection</td></tr>"
|
||||
else
|
||||
cRoot:Get():GetWorld(WORK_WORLD):ForEachPlayer( AddPlayerToTable )
|
||||
if( PlayerNum == 0 ) then
|
||||
Content = Content .. "<tr><td>No connected players</td></tr>"
|
||||
end
|
||||
end
|
||||
Content = Content .. "</table>"
|
||||
Content = Content .. "<br>"
|
||||
return Content
|
||||
local function Buttons_Player( Name )
|
||||
return "<form method='POST'><input type='hidden' name='PlayerName' value='"..Name.."'><input type='submit' name='PlayerExact' value='Exact'><input type='submit' name='Player3x3' value='3x3'></form>"
|
||||
end
|
||||
|
||||
local function Button_World( Name )
|
||||
return "<form method='POST'><input type='hidden' name='WorldName' value='"..Name.."'><input type='submit' name='SelectWorld' value='Select'></form>"
|
||||
end
|
||||
|
||||
function HandleRequest_Generation( Request )
|
||||
local Content = ""
|
||||
if (Request.PostParams["AGHRRRR"] ~= nil) then
|
||||
GENERATION_STATE = 0
|
||||
WW_instance:SaveAllChunks()
|
||||
WW_instance:UnloadUnusedChunks()
|
||||
LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works ABORTED by admin")
|
||||
end
|
||||
--Content = Content .. "<head><meta http-equiv=\"refresh\" content=\"2;\"></head>"
|
||||
-- PROCESSING
|
||||
--------------------------------------------------------------------------------------------------
|
||||
local function ProcessingContent()
|
||||
local _small_content = ""
|
||||
_small_content = _small_content .. "<head><meta http-equiv=\"refresh\" content=\"2;\"></head>"
|
||||
_small_content = _small_content .. "<h4>World for operations:</h4>"..WORK_WORLD
|
||||
if (OPERATION_CODE == 0) then
|
||||
_small_content = _small_content .. "<h4>Operation:</h4>Generation"
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
_small_content = _small_content .. "<h4>Operation:</h4>Regeneration"
|
||||
end
|
||||
_small_content = _small_content .. "<h4>Area: </h4>["..AreaStartX..":"..AreaStartZ.."] ["..AreaEndX..":"..AreaEndZ.."]"
|
||||
_small_content = _small_content .. "<h4>Progress:</h4>"..CURRENT.."/"..TOTAL
|
||||
_small_content = _small_content .. "<br>"
|
||||
_small_content = _small_content .. "<form method='POST'>"
|
||||
_small_content = _small_content .. "<input type='submit' name='AGHRRRR' value='Stop'>"
|
||||
_small_content = _small_content .. "</form>"
|
||||
return _small_content
|
||||
end
|
||||
if (GENERATION_STATE == 2 or GENERATION_STATE == 4) then
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
-- SELECTING
|
||||
--------------------------------------------------------------------------------------------------
|
||||
if ( Request.PostParams["FormSetWorld"] ) then
|
||||
WORK_WORLD = Request.PostParams["FormWorldName"]
|
||||
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
|
||||
end
|
||||
|
||||
if( Request.PostParams["SelectWorld"] ~= nil
|
||||
and Request.PostParams["WorldName"] ~= nil ) then -- World is selected!
|
||||
WORK_WORLD = Request.PostParams["WorldName"]
|
||||
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
|
||||
end
|
||||
|
||||
if(Request.PostParams["OperationGenerate"] ~= nil) then
|
||||
OPERATION_CODE = 0
|
||||
end
|
||||
if(Request.PostParams["OperationReGenerate"] ~= nil) then
|
||||
OPERATION_CODE = 1
|
||||
end
|
||||
|
||||
if (GENERATION_STATE == 0) then
|
||||
if( Request.PostParams["FormAreaStartX"] ~= nil
|
||||
and Request.PostParams["FormAreaStartZ"] ~= nil
|
||||
and Request.PostParams["FormAreaEndX"] ~= nil
|
||||
and Request.PostParams["FormAreaEndZ"] ~= nil ) then --(Re)Generation valid!
|
||||
-- COMMON (Re)gen
|
||||
if( Request.PostParams["StartArea"]) then
|
||||
AreaStartX = tonumber(Request.PostParams["FormAreaStartX"])
|
||||
AreaStartZ = tonumber(Request.PostParams["FormAreaStartZ"])
|
||||
AreaEndX = tonumber(Request.PostParams["FormAreaEndX"])
|
||||
AreaEndZ = tonumber(Request.PostParams["FormAreaEndZ"])
|
||||
|
||||
PLUGIN.IniFile:DeleteValue("Area data", "StartX")
|
||||
PLUGIN.IniFile:DeleteValue("Area data", "StartZ")
|
||||
PLUGIN.IniFile:DeleteValue("Area data", "EndX")
|
||||
PLUGIN.IniFile:DeleteValue("Area data", "EndZ")
|
||||
PLUGIN.IniFile:SetValueI("Area data", "StartX", AreaStartX)
|
||||
PLUGIN.IniFile:SetValueI("Area data", "StartZ", AreaStartZ)
|
||||
PLUGIN.IniFile:SetValueI("Area data", "EndX", AreaEndX)
|
||||
PLUGIN.IniFile:SetValueI("Area data", "EndZ", AreaEndZ)
|
||||
if (OPERATION_CODE == 0) then
|
||||
GENERATION_STATE = 1
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
GENERATION_STATE = 3
|
||||
end
|
||||
PLUGIN.IniFile:WriteFile()
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
if( Request.PostParams["FormRadialX"] ~= nil
|
||||
and Request.PostParams["FormRadialZ"] ~= nil
|
||||
and Request.PostParams["FormRadius"] ~= nil ) then --(Re)Generation valid!
|
||||
-- COMMON (Re)gen
|
||||
if( Request.PostParams["StartRadial"]) then
|
||||
RadialX = tonumber(Request.PostParams["FormRadialX"])
|
||||
RadialZ = tonumber(Request.PostParams["FormRadialZ"])
|
||||
Radius = tonumber(Request.PostParams["FormRadius"])
|
||||
AreaStartX = RadialX - Radius
|
||||
AreaStartZ = RadialZ - Radius
|
||||
AreaEndX = RadialX + Radius
|
||||
AreaEndZ = RadialZ + Radius
|
||||
|
||||
PLUGIN.IniFile:DeleteValue("Radial data", "RadialX")
|
||||
PLUGIN.IniFile:DeleteValue("Radial data", "RadialZ")
|
||||
PLUGIN.IniFile:DeleteValue("Radial data", "Radius")
|
||||
PLUGIN.IniFile:SetValueI("Radial data", "RadialX", RadialX)
|
||||
PLUGIN.IniFile:SetValueI("Radial data", "RadialZ", RadialZ)
|
||||
PLUGIN.IniFile:SetValueI("Radial data", "Radius", Radius)
|
||||
if (OPERATION_CODE == 0) then
|
||||
GENERATION_STATE = 1
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
GENERATION_STATE = 3
|
||||
end
|
||||
PLUGIN.IniFile:WriteFile()
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
-- POINT REGEN!
|
||||
if( Request.PostParams["FormPointX"] ~= nil
|
||||
and Request.PostParams["FormPointZ"] ~= nil ) then --ReGeneration valid!
|
||||
-- EXACT
|
||||
if ( Request.PostParams["PointExact"] ~= nil) then
|
||||
AreaStartX = tonumber(Request.PostParams["FormPointX"])
|
||||
AreaStartZ = tonumber(Request.PostParams["FormPointZ"])
|
||||
AreaEndX = AreaStartX
|
||||
AreaEndZ = AreaStartZ
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
-- 3x3
|
||||
if ( Request.PostParams["Point3x3"] ~= nil) then
|
||||
AreaStartX = tonumber(Request.PostParams["FormPointX"]) - 1
|
||||
AreaStartZ = tonumber(Request.PostParams["FormPointZ"]) - 1
|
||||
AreaEndX = AreaStartX + 2
|
||||
AreaEndZ = AreaStartZ + 2
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
|
||||
local GetAreaByPlayer = function(Player)
|
||||
-- Player is valid only within this function, it cannot be stord and used later!
|
||||
AreaStartX = Player:GetChunkX()
|
||||
AreaStartZ = Player:GetChunkZ()
|
||||
end
|
||||
-- PLAYERS REGEN!
|
||||
if( Request.PostParams["PlayerExact"] ~= nil
|
||||
and Request.PostParams["PlayerName"] ~= nil ) then -- Making BOOM! I meant, regenereate...
|
||||
cRoot:Get():GetWorld(WORK_WORLD):DoWithPlayer(Request.PostParams["PlayerName"],GetAreaByPlayer)
|
||||
AreaEndX = AreaStartX
|
||||
AreaEndZ = AreaStartZ
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
if( Request.PostParams["Player3x3"] ~= nil
|
||||
and Request.PostParams["PlayerName"] ~= nil ) then -- Making BOOM! I meant, regenereate...
|
||||
cRoot:Get():GetWorld(WORK_WORLD):DoWithPlayer(Request.PostParams["PlayerName"],GetAreaByPlayer)
|
||||
AreaStartX = AreaStartX - 1
|
||||
AreaStartZ = AreaStartZ - 1
|
||||
AreaEndX = AreaStartX + 2
|
||||
AreaEndZ = AreaStartZ + 2
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
|
||||
--Content = Content .. "<h4>World for operations: " .. WORK_WORLD .. "</h4>"
|
||||
--Content = Content .. "<form method='POST'>"
|
||||
--Content = Content .. "<input type='text' name='FormWorldName' value='Input world name here'><input type='submit' name='FormSetWorld' value='Set world'>"
|
||||
--Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING WORK_WORLD
|
||||
Content = Content .. "<h4>World for operations: " .. WORK_WORLD .. "</h4>"
|
||||
Content = Content .. "<table>"
|
||||
local WorldNum = 0
|
||||
local AddWorldToTable = function(World)
|
||||
WorldNum = WorldNum + 1
|
||||
Content = Content .. "<tr>"
|
||||
Content = Content .. "<td style='width: 10px;'>" .. WorldNum .. ".</td>"
|
||||
Content = Content .. "<td>" .. World:GetName() .. "</td>"
|
||||
Content = Content .. "<td>" .. Button_World(World:GetName()) .. "</td>"
|
||||
Content = Content .. "</tr>"
|
||||
end
|
||||
cRoot:Get():ForEachWorld(AddWorldToTable)
|
||||
if( WorldNum == 0 ) then
|
||||
Content = Content .. "<tr><td>No worlds! O_O</td></tr>"
|
||||
end
|
||||
Content = Content .. "</table>"
|
||||
Content = Content .. "<br>"
|
||||
|
||||
-- SELECTING OPERATION
|
||||
if (OPERATION_CODE == 0) then
|
||||
Content = Content .. "<h4>Operation: Generation</h4>"
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
Content = Content .. "<h4>Operation: Regeneration</h4>"
|
||||
end
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='submit' name='OperationGenerate' value='Generation'>"
|
||||
Content = Content .. "<input type='submit' name='OperationReGenerate' value='Regeneration'>"
|
||||
Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING AREA
|
||||
Content = Content .. "<h4>Area: </h4>Start X, Start Z; End X, End Z"
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='text' name='FormAreaStartX' value='" .. AreaStartX .. "'><input type='text' name='FormAreaStartZ' value='" .. AreaStartZ .. "'>"
|
||||
Content = Content .. "<input type='text' name='FormAreaEndX' value='" .. AreaEndX .. "'><input type='text' name='FormAreaEndZ' value='" .. AreaEndZ .. "'>"
|
||||
Content = Content .. "<input type='submit' name='StartArea' value='Start'>"
|
||||
Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING RADIAL
|
||||
Content = Content .. "<h4>Radial: </h4>Center X, Center Z, Raduis (0 to any)"
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='text' name='FormRadialX' value='" .. RadialX .. "'><input type='text' name='FormRadialZ' value='" .. RadialZ .. "'><input type='text' name='FormRadius' value='" .. Radius .. "'>"
|
||||
Content = Content .. "<input type='submit' name='StartRadial' value='Start'>"
|
||||
Content = Content .. "</form>"
|
||||
Content = Content .. "<br>"
|
||||
Content = Content .. "<br>"
|
||||
Content = Content .. "<br>"
|
||||
|
||||
-- SELECTING POINT
|
||||
Content = Content .. "<h4>Point regeneration:</h4> X, Z"
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='text' name='FormPointX' value='0'><input type='text' name='FormPointZ' value='0'>"
|
||||
Content = Content .. "<input type='submit' name='PointExact' value='Exact'>"
|
||||
Content = Content .. "<input type='submit' name='Point3x3' value='3x3'>"
|
||||
Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING PLAYERS
|
||||
Content = Content .. "<h4>Player-based regeneration:</h4>"
|
||||
Content = Content .. "<table>"
|
||||
local PlayerNum = 0
|
||||
local AddPlayerToTable = function( Player )
|
||||
PlayerNum = PlayerNum + 1
|
||||
Content = Content .. "<tr>"
|
||||
Content = Content .. "<td style='width: 10px;'>" .. PlayerNum .. ".</td>"
|
||||
Content = Content .. "<td>" .. Player:GetName() .. "</td>"
|
||||
Content = Content .. "<td>" .. Buttons_Player(Player:GetName()) .. "</td>"
|
||||
Content = Content .. "</tr>"
|
||||
end
|
||||
if (cRoot:Get():GetWorld(WORK_WORLD) == nil) then
|
||||
Content = Content .. "<tr><td>Incorrect world selection</td></tr>"
|
||||
else
|
||||
cRoot:Get():GetWorld(WORK_WORLD):ForEachPlayer( AddPlayerToTable )
|
||||
if( PlayerNum == 0 ) then
|
||||
Content = Content .. "<tr><td>No connected players</td></tr>"
|
||||
end
|
||||
end
|
||||
Content = Content .. "</table>"
|
||||
Content = Content .. "<br>"
|
||||
return Content
|
||||
end
|
File diff suppressed because it is too large
Load Diff
@ -1,83 +1,83 @@
|
||||
|
||||
-- DiamondMover.lua
|
||||
|
||||
-- An example Lua plugin using the cBlockArea object
|
||||
-- When a player rclks with a diamond in their hand, an area around the clicked block is moved in the direction the player is facing
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- Global variables
|
||||
PLUGIN = {} -- Reference to own plugin object
|
||||
MOVER_SIZE_X = 4;
|
||||
MOVER_SIZE_Y = 4;
|
||||
MOVER_SIZE_Z = 4;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function Initialize(Plugin)
|
||||
PLUGIN = Plugin;
|
||||
|
||||
Plugin:SetName("DiamondMover");
|
||||
Plugin:SetVersion(1);
|
||||
|
||||
PluginManager = cRoot:Get():GetPluginManager();
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USED_ITEM);
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsedItem(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, CursorY, CursorZ)
|
||||
|
||||
-- Don't check if the direction is in the air
|
||||
if (BlockFace == -1) then
|
||||
return false;
|
||||
end;
|
||||
|
||||
if (Player:HasPermission("diamondmover.move") == false) then
|
||||
return true;
|
||||
end;
|
||||
|
||||
-- Rclk with a diamond to push in the direction the player is facing
|
||||
if (Player:GetEquippedItem().m_ItemType == E_ITEM_DIAMOND) then
|
||||
local Area = cBlockArea();
|
||||
Area:Read(Player:GetWorld(),
|
||||
BlockX - MOVER_SIZE_X, BlockX + MOVER_SIZE_X,
|
||||
BlockY - MOVER_SIZE_Y, BlockY + MOVER_SIZE_Y,
|
||||
BlockZ - MOVER_SIZE_Z, BlockZ + MOVER_SIZE_Z
|
||||
);
|
||||
|
||||
local PlayerPitch = Player:GetPitch();
|
||||
if (PlayerPitch < -70) then -- looking up
|
||||
BlockY = BlockY + 1;
|
||||
else
|
||||
if (PlayerPitch > 70) then -- looking down
|
||||
BlockY = BlockY - 1;
|
||||
else
|
||||
local PlayerRot = Player:GetRotation() + 180; -- Convert [-180, 180] into [0, 360] for simpler conditions
|
||||
if ((PlayerRot < 45) or (PlayerRot > 315)) then
|
||||
BlockZ = BlockZ - 1;
|
||||
else
|
||||
if (PlayerRot < 135) then
|
||||
BlockX = BlockX + 1;
|
||||
else
|
||||
if (PlayerRot < 225) then
|
||||
BlockZ = BlockZ + 1;
|
||||
else
|
||||
BlockX = BlockX - 1;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
Area:Write(Player:GetWorld(), BlockX - MOVER_SIZE_X, BlockY - MOVER_SIZE_Y, BlockZ - MOVER_SIZE_Z);
|
||||
return false;
|
||||
end
|
||||
|
||||
-- DiamondMover.lua
|
||||
|
||||
-- An example Lua plugin using the cBlockArea object
|
||||
-- When a player rclks with a diamond in their hand, an area around the clicked block is moved in the direction the player is facing
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- Global variables
|
||||
PLUGIN = {} -- Reference to own plugin object
|
||||
MOVER_SIZE_X = 4;
|
||||
MOVER_SIZE_Y = 4;
|
||||
MOVER_SIZE_Z = 4;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function Initialize(Plugin)
|
||||
PLUGIN = Plugin;
|
||||
|
||||
Plugin:SetName("DiamondMover");
|
||||
Plugin:SetVersion(1);
|
||||
|
||||
PluginManager = cRoot:Get():GetPluginManager();
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USED_ITEM);
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsedItem(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, CursorY, CursorZ)
|
||||
|
||||
-- Don't check if the direction is in the air
|
||||
if (BlockFace == -1) then
|
||||
return false;
|
||||
end;
|
||||
|
||||
if (Player:HasPermission("diamondmover.move") == false) then
|
||||
return true;
|
||||
end;
|
||||
|
||||
-- Rclk with a diamond to push in the direction the player is facing
|
||||
if (Player:GetEquippedItem().m_ItemType == E_ITEM_DIAMOND) then
|
||||
local Area = cBlockArea();
|
||||
Area:Read(Player:GetWorld(),
|
||||
BlockX - MOVER_SIZE_X, BlockX + MOVER_SIZE_X,
|
||||
BlockY - MOVER_SIZE_Y, BlockY + MOVER_SIZE_Y,
|
||||
BlockZ - MOVER_SIZE_Z, BlockZ + MOVER_SIZE_Z
|
||||
);
|
||||
|
||||
local PlayerPitch = Player:GetPitch();
|
||||
if (PlayerPitch < -70) then -- looking up
|
||||
BlockY = BlockY + 1;
|
||||
else
|
||||
if (PlayerPitch > 70) then -- looking down
|
||||
BlockY = BlockY - 1;
|
||||
else
|
||||
local PlayerRot = Player:GetRotation() + 180; -- Convert [-180, 180] into [0, 360] for simpler conditions
|
||||
if ((PlayerRot < 45) or (PlayerRot > 315)) then
|
||||
BlockZ = BlockZ - 1;
|
||||
else
|
||||
if (PlayerRot < 135) then
|
||||
BlockX = BlockX + 1;
|
||||
else
|
||||
if (PlayerRot < 225) then
|
||||
BlockZ = BlockZ + 1;
|
||||
else
|
||||
BlockX = BlockX - 1;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
Area:Write(Player:GetWorld(), BlockX - MOVER_SIZE_X, BlockY - MOVER_SIZE_Y, BlockZ - MOVER_SIZE_Z);
|
||||
return false;
|
||||
end
|
||||
end
|
@ -1,28 +1,28 @@
|
||||
-- Global variables
|
||||
PLUGIN = {} -- Reference to own plugin object
|
||||
CHEST_WIDTH = 9
|
||||
HANDY_VERSION = 1
|
||||
--[[
|
||||
|
||||
Handy is a plugin for other plugins. It contain no commands, no hooks, but functions to ease plugins developers' life.
|
||||
|
||||
API:
|
||||
|
||||
|
||||
TODO:
|
||||
1. GetChestSlot wrapper, so it will detect double chest neighbour chest and will be able to access it.
|
||||
]]
|
||||
|
||||
function Initialize(Plugin)
|
||||
PLUGIN = Plugin
|
||||
PLUGIN:SetName("Handy")
|
||||
PLUGIN:SetVersion(HANDY_VERSION)
|
||||
|
||||
PluginManager = cRoot:Get():GetPluginManager()
|
||||
LOG("Initialized " .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion())
|
||||
return true
|
||||
end
|
||||
|
||||
function OnDisable()
|
||||
LOG(PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " is shutting down...")
|
||||
-- Global variables
|
||||
PLUGIN = {} -- Reference to own plugin object
|
||||
CHEST_WIDTH = 9
|
||||
HANDY_VERSION = 1
|
||||
--[[
|
||||
|
||||
Handy is a plugin for other plugins. It contain no commands, no hooks, but functions to ease plugins developers' life.
|
||||
|
||||
API:
|
||||
|
||||
|
||||
TODO:
|
||||
1. GetChestSlot wrapper, so it will detect double chest neighbour chest and will be able to access it.
|
||||
]]
|
||||
|
||||
function Initialize(Plugin)
|
||||
PLUGIN = Plugin
|
||||
PLUGIN:SetName("Handy")
|
||||
PLUGIN:SetVersion(HANDY_VERSION)
|
||||
|
||||
PluginManager = cRoot:Get():GetPluginManager()
|
||||
LOG("Initialized " .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion())
|
||||
return true
|
||||
end
|
||||
|
||||
function OnDisable()
|
||||
LOG(PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " is shutting down...")
|
||||
end
|
@ -1,355 +1,355 @@
|
||||
--[[
|
||||
General stuff
|
||||
]]
|
||||
-- Returns Handy plugin version number
|
||||
function GetHandyVersion()
|
||||
return HANDY_VERSION
|
||||
end
|
||||
-- Checks if handy is in proper version
|
||||
function CheckForRequiedVersion(IN_version)
|
||||
if (IN_version > HANDY_VERSION) then return false end
|
||||
return true
|
||||
end
|
||||
--[[
|
||||
MCS-specific _functions and nasty hacks :D
|
||||
]]
|
||||
-- There's a "GetChestHeight" function inside source code, but it's not lua-exported
|
||||
function GetChestHeightCheat(IN_chest)
|
||||
if (IN_chest:GetSlot(28) == nil) then -- this means we're trying to get double chest slot and FAIL
|
||||
LOGWARN("HANDY: single chest checked")
|
||||
return 3
|
||||
end
|
||||
LOGWARN("HANDY: double chest checked")
|
||||
return 6
|
||||
end
|
||||
-- Those two checks how many items of given IN_itemID chest and player have, and how much they could fit inside them
|
||||
function ReadChestForItem(IN_chest, IN_itemID)
|
||||
local _items_found = 0
|
||||
local _free_space = 0
|
||||
-- stalk through chest slots...
|
||||
local _slot_counter = 0
|
||||
local _slot_item
|
||||
local _item_max_stack = GetItemMaxStack(IN_itemID)
|
||||
while true do
|
||||
_slot_item = IN_chest:GetSlot(_slot_counter)
|
||||
if (_slot_item ~= nil) then
|
||||
if (_slot_item.m_ItemID == IN_itemID) then
|
||||
_items_found = _items_found + _slot_item.m_ItemCount
|
||||
_free_space = _free_space + (_item_max_stack - _slot_item.m_ItemCount)
|
||||
end
|
||||
if (_slot_item:IsEmpty() == true) then
|
||||
_free_space = _free_space + _item_max_stack
|
||||
end
|
||||
end
|
||||
_slot_counter = _slot_counter + 1
|
||||
if (_slot_counter == CHEST_WIDTH*GetChestHeightCheat(IN_chest)) then
|
||||
break
|
||||
end
|
||||
end
|
||||
return _items_found, _free_space
|
||||
end
|
||||
function ReadPlayerForItem(IN_player, IN_itemID)
|
||||
local _items_found = 0
|
||||
local _free_space = 0
|
||||
-- stalk through IN_player inventory slots...
|
||||
local _slot_counter = 9
|
||||
if (ItemIsArmor(IN_itemID) == true) then _slot_counter = 5 end
|
||||
local _slot_item
|
||||
local _item_max_stack = GetItemMaxStack(IN_itemID)
|
||||
while true do
|
||||
_slot_item = IN_player:GetInventory():GetSlot(_slot_counter)
|
||||
if (_slot_item ~= nil) then
|
||||
if (_slot_item.m_ItemID == IN_itemID) then
|
||||
_items_found = _items_found + _slot_item.m_ItemCount
|
||||
_free_space = _free_space + (_item_max_stack - _slot_item.m_ItemCount)
|
||||
end
|
||||
if (_slot_item:IsEmpty() == true) then
|
||||
_free_space = _free_space + _item_max_stack
|
||||
end
|
||||
end
|
||||
_slot_counter = _slot_counter + 1
|
||||
if (_slot_counter == 45) then
|
||||
break
|
||||
end
|
||||
end
|
||||
return _items_found, _free_space
|
||||
end
|
||||
-- Following functions are for chest-related operations (since noone was bothered writing them in MCS code)
|
||||
-- BEWARE! Those assume you did checked if chest has items/space in it!
|
||||
function TakeItemsFromChest(IN_chest, IN_itemID, IN_ammount) -- UNSAFE! CHECK FOR ITEMS FIRST!!
|
||||
-- stalk through chest slots...
|
||||
local _slot_counter = 0
|
||||
local _slot_item
|
||||
local _take_count = IN_ammount
|
||||
while true do
|
||||
_slot_item = IN_chest:GetSlot(_slot_counter)
|
||||
if (_slot_item ~= nil) then
|
||||
if (_slot_item.m_ItemID == IN_itemID) then
|
||||
-- assuming player have enought money
|
||||
if (_take_count > 0) then
|
||||
if (_take_count > _slot_item.m_ItemCount) then
|
||||
_take_count = _take_count - _slot_item.m_ItemCount
|
||||
IN_chest:SetSlot(_slot_counter, cItem()) -- a bit hacky, can't make cItem:Clear() work(
|
||||
else
|
||||
local _left_count = _slot_item.m_ItemCount - _take_count
|
||||
IN_chest:SetSlot(_slot_counter, cItem(_slot_item.m_ItemID, _left_count)) -- a bit hacky
|
||||
_take_count = 0
|
||||
end
|
||||
end
|
||||
if (_take_count == 0) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
_slot_counter = _slot_counter + 1
|
||||
if (_slot_counter == CHEST_WIDTH*GetChestHeightCheat(IN_chest)) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
function PutItemsToChest(IN_chest, IN_itemID, IN_ammount) -- UNSAFE! CHECK FOR SPACE FIRST!!
|
||||
-- stalk through chest slots...
|
||||
local _slot_counter = 0
|
||||
local _slot_item
|
||||
local _put_count = IN_ammount
|
||||
local _max_stack = GetItemMaxStack(IN_itemID)
|
||||
while true do
|
||||
_slot_item = IN_chest:GetSlot(_slot_counter)
|
||||
local _portion = 0
|
||||
local _ammount_to_set = 0
|
||||
if (_slot_item ~= nil) then
|
||||
if (_slot_item:IsEmpty() == true) then
|
||||
_portion = math.min(_max_stack, _put_count)
|
||||
_ammount_to_set = _portion
|
||||
else
|
||||
if (_slot_item.m_ItemID == IN_itemID) then
|
||||
-- choose between how much we need to put and how much free space left
|
||||
_portion = math.min(_put_count, _max_stack - _slot_item.m_ItemCount)
|
||||
_ammount_to_set = _slot_item.m_ItemCount + _portion
|
||||
end
|
||||
end
|
||||
end
|
||||
IN_chest:SetSlot(_slot_counter, cItem(IN_itemID, _ammount_to_set)) -- we add max stack to chest
|
||||
_put_count = _put_count - _portion
|
||||
if (_put_count == 0) then break end
|
||||
_slot_counter = _slot_counter + 1
|
||||
if (_slot_counter == CHEST_WIDTH*GetChestHeightCheat(IN_chest)) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Similar to chest-related.
|
||||
function TakeItemsFromPlayer(IN_player, IN_itemID, IN_ammount) -- UNSAFE! CHECK FIRST!
|
||||
local _put_count = IN_ammount
|
||||
local _max_stack = GetItemMaxStack(IN_itemID)
|
||||
while true do
|
||||
local _portion = math.min(_max_stack, _put_count)
|
||||
IN_player:GetInventory():RemoveItem(cItem(IN_itemID, _portion))
|
||||
_put_count = _put_count - _portion
|
||||
if (_put_count == 0) then break end
|
||||
end
|
||||
end
|
||||
function GiveItemsToPlayer(IN_player, IN_itemID, IN_ammount) -- UNSAFE! CHECK FIRST!
|
||||
local _put_count = IN_ammount
|
||||
local _max_stack = GetItemMaxStack(IN_itemID)
|
||||
while true do
|
||||
local _portion = math.min(_max_stack, _put_count)
|
||||
IN_player:GetInventory():AddItem(cItem(IN_itemID, _portion))
|
||||
_put_count = _put_count - _portion
|
||||
if (_put_count == 0) then break end
|
||||
end
|
||||
end
|
||||
-- This function returns item max stack for a given itemID. It uses vanilla max stack size, and uses several non-common items notations;
|
||||
-- Those are:
|
||||
-- oneonerecord (because aparently 11record wasn't the best idea in lua scripting application)
|
||||
-- carrotonastick (because it wasn't added to items.txt yet)
|
||||
-- waitrecord (for same reason)
|
||||
-- Feel free to ignore the difference, or to add those to items.txt
|
||||
function GetItemMaxStack(IN_itemID)
|
||||
local _result = 64
|
||||
-- Tools and swords
|
||||
if (IN_itemID == woodensword) then _result = 1 end
|
||||
if (IN_itemID == woodenshovel) then _result = 1 end
|
||||
if (IN_itemID == woodenpickaxe) then _result = 1 end
|
||||
if (IN_itemID == woodenaxe) then _result = 1 end
|
||||
if (IN_itemID == woodenhoe) then _result = 1 end
|
||||
if (IN_itemID == stonesword) then _result = 1 end
|
||||
if (IN_itemID == stoneshovel) then _result = 1 end
|
||||
if (IN_itemID == stonepickaxe) then _result = 1 end
|
||||
if (IN_itemID == stoneaxe) then _result = 1 end
|
||||
if (IN_itemID == stonehoe) then _result = 1 end
|
||||
if (IN_itemID == ironsword) then _result = 1 end
|
||||
if (IN_itemID == ironshovel) then _result = 1 end
|
||||
if (IN_itemID == ironpickaxe) then _result = 1 end
|
||||
if (IN_itemID == ironaxe) then _result = 1 end
|
||||
if (IN_itemID == ironhoe) then _result = 1 end
|
||||
if (IN_itemID == diamondsword) then _result = 1 end
|
||||
if (IN_itemID == diamondshovel) then _result = 1 end
|
||||
if (IN_itemID == diamondpickaxe) then _result = 1 end
|
||||
if (IN_itemID == diamondaxe) then _result = 1 end
|
||||
if (IN_itemID == diamondhoe) then _result = 1 end
|
||||
if (IN_itemID == goldensword) then _result = 1 end
|
||||
if (IN_itemID == goldenshovel) then _result = 1 end
|
||||
if (IN_itemID == goldenpickaxe) then _result = 1 end
|
||||
if (IN_itemID == goldenaxe) then _result = 1 end
|
||||
if (IN_itemID == goldenhoe) then _result = 1 end
|
||||
|
||||
if (IN_itemID == flintandsteel) then _result = 1 end
|
||||
if (IN_itemID == bow) then _result = 1 end
|
||||
if (IN_itemID == sign) then _result = 16 end
|
||||
if (IN_itemID == woodendoor) then _result = 1 end
|
||||
if (IN_itemID == irondoor) then _result = 1 end
|
||||
if (IN_itemID == cake) then _result = 1 end
|
||||
if (IN_itemID == cauldron) then _result = 1 end
|
||||
if (IN_itemID == mushroomstew) then _result = 1 end
|
||||
if (IN_itemID == painting) then _result = 1 end
|
||||
if (IN_itemID == bucket) then _result = 16 end
|
||||
if (IN_itemID == waterbucket) then _result = 1 end
|
||||
if (IN_itemID == lavabucket) then _result = 1 end
|
||||
if (IN_itemID == minecart) then _result = 1 end
|
||||
if (IN_itemID == saddle) then _result = 1 end
|
||||
if (IN_itemID == snowball) then _result = 16 end
|
||||
if (IN_itemID == boat) then _result = 1 end
|
||||
if (IN_itemID == milkbucket) then _result = 1 end
|
||||
if (IN_itemID == storageminecart) then _result = 1 end
|
||||
if (IN_itemID == poweredminecart) then _result = 1 end
|
||||
if (IN_itemID == egg) then _result = 16 end
|
||||
if (IN_itemID == fishingrod) then _result = 1 end
|
||||
if (IN_itemID == bed) then _result = 1 end
|
||||
if (IN_itemID == map) then _result = 1 end
|
||||
if (IN_itemID == shears) then _result = 1 end
|
||||
if (IN_itemID == enderpearl) then _result = 16 end
|
||||
if (IN_itemID == potion) then _result = 1 end
|
||||
if (IN_itemID == spawnegg) then _result = 1 end
|
||||
if (IN_itemID == bookandquill) then _result = 1 end
|
||||
if (IN_itemID == writtenbook) then _result = 1 end
|
||||
if (IN_itemID == carrotonastick) then _result = 1 end
|
||||
|
||||
if (IN_itemID == goldrecord) then _result = 1 end
|
||||
if (IN_itemID == greenrecord) then _result = 1 end
|
||||
if (IN_itemID == blocksrecord) then _result = 1 end
|
||||
if (IN_itemID == chirprecord) then _result = 1 end
|
||||
if (IN_itemID == farrecord) then _result = 1 end
|
||||
if (IN_itemID == mallrecord) then _result = 1 end
|
||||
if (IN_itemID == mellohirecord) then _result = 1 end
|
||||
if (IN_itemID == stalrecord) then _result = 1 end
|
||||
if (IN_itemID == stradrecord) then _result = 1 end
|
||||
if (IN_itemID == wardrecord) then _result = 1 end
|
||||
if (IN_itemID == oneonerecord) then _result = 1 end
|
||||
if (IN_itemID == waitrecord) then _result = 1 end
|
||||
|
||||
--if (IN_itemID == xxxxxxxxx) then _result = 1 end
|
||||
|
||||
if (IN_itemID == leatherhelmet) then _result = 1 end
|
||||
if (IN_itemID == leatherchestplate) then _result = 1 end
|
||||
if (IN_itemID == leatherpants) then _result = 1 end
|
||||
if (IN_itemID == leatherboots) then _result = 1 end
|
||||
|
||||
if (IN_itemID == chainmailhelmet) then _result = 1 end
|
||||
if (IN_itemID == chainmailchestplate) then _result = 1 end
|
||||
if (IN_itemID == chainmailpants) then _result = 1 end
|
||||
if (IN_itemID == chainmailboots) then _result = 1 end
|
||||
|
||||
if (IN_itemID == ironhelmet) then _result = 1 end
|
||||
if (IN_itemID == ironchestplate) then _result = 1 end
|
||||
if (IN_itemID == ironpants) then _result = 1 end
|
||||
if (IN_itemID == ironboots) then _result = 1 end
|
||||
|
||||
if (IN_itemID == diamondhelmet) then _result = 1 end
|
||||
if (IN_itemID == diamondchestplate) then _result = 1 end
|
||||
if (IN_itemID == diamondpants) then _result = 1 end
|
||||
if (IN_itemID == diamondboots) then _result = 1 end
|
||||
|
||||
if (IN_itemID == goldenhelmet) then _result = 1 end
|
||||
if (IN_itemID == goldenchestplate) then _result = 1 end
|
||||
if (IN_itemID == goldenpants) then _result = 1 end
|
||||
if (IN_itemID == goldenboots) then _result = 1 end
|
||||
return _result
|
||||
end
|
||||
function ItemIsArmor(IN_itemID)
|
||||
local _result = false
|
||||
if (IN_itemID == leatherhelmet) then _result = true end
|
||||
if (IN_itemID == leatherchestplate) then _result = true end
|
||||
if (IN_itemID == leatherpants) then _result = true end
|
||||
if (IN_itemID == leatherboots) then _result = true end
|
||||
|
||||
if (IN_itemID == chainmailhelmet) then _result = true end
|
||||
if (IN_itemID == chainmailchestplate) then _result = true end
|
||||
if (IN_itemID == chainmailpants) then _result = true end
|
||||
if (IN_itemID == chainmailboots) then _result = true end
|
||||
|
||||
if (IN_itemID == ironhelmet) then _result = true end
|
||||
if (IN_itemID == ironchestplate) then _result = true end
|
||||
if (IN_itemID == ironpants) then _result = true end
|
||||
if (IN_itemID == ironboots) then _result = true end
|
||||
|
||||
if (IN_itemID == diamondhelmet) then _result = true end
|
||||
if (IN_itemID == diamondchestplate) then _result = true end
|
||||
if (IN_itemID == diamondpants) then _result = true end
|
||||
if (IN_itemID == diamondboots) then _result = true end
|
||||
|
||||
if (IN_itemID == goldenhelmet) then _result = true end
|
||||
if (IN_itemID == goldenchestplate) then _result = true end
|
||||
if (IN_itemID == goldenpants) then _result = true end
|
||||
if (IN_itemID == goldenboots) then _result = true end
|
||||
return _result
|
||||
end
|
||||
-- Returns full-length playername for a short name (usefull for parsing commands)
|
||||
function GetExactPlayername(IN_playername)
|
||||
local _result = IN_playername
|
||||
local function SetProcessingPlayername(IN_player)
|
||||
_result = IN_player:GetName()
|
||||
end
|
||||
cRoot:Get():FindAndDoWithPlayer(IN_playername, SetProcessingPlayername)
|
||||
return _result
|
||||
end
|
||||
function GetPlayerByName(IN_playername)
|
||||
local _player
|
||||
local PlayerSetter = function (Player)
|
||||
_player = Player
|
||||
end
|
||||
cRoot:Get():FindAndDoWithPlayer(IN_playername, PlayerSetter)
|
||||
return _player
|
||||
end
|
||||
--[[
|
||||
Not-so-usual math _functions
|
||||
]]
|
||||
-- Rounds floating point number. Because lua guys think this function doesn't deserve to be presented in lua's math
|
||||
function round(IN_x)
|
||||
if (IN_x%2 ~= 0.5) then
|
||||
return math.floor(IN_x+0.5)
|
||||
end
|
||||
return IN_x-0.5
|
||||
end
|
||||
--[[
|
||||
Functions I use for filework and stringswork
|
||||
]]
|
||||
function PluralString(IN_value, IN_singular_string, IN_plural_string)
|
||||
local _value_string = tostring(IN_value)
|
||||
if (_value_string[#_value_string] == "1") then
|
||||
return IN_singular_string
|
||||
end
|
||||
return IN_plural_string
|
||||
end
|
||||
function PluralItemName(IN_itemID, IN_ammount) -- BEWARE! TEMPORAL SOLUTION THERE! :D
|
||||
local _value_string = tostring(IN_value)
|
||||
local _name = ""
|
||||
if (_value_string[#_value_string] == "1") then
|
||||
-- singular names
|
||||
_name = ItemTypeToString(IN_itemID)
|
||||
else
|
||||
-- plural names
|
||||
_name = ItemTypeToString(IN_itemID).."s"
|
||||
end
|
||||
return _name
|
||||
end
|
||||
-- for filewriting purposes. 0 = false, 1 = true
|
||||
function StringToBool(value)
|
||||
if value=="1" then return true end
|
||||
return false
|
||||
end
|
||||
-- same, but reversal
|
||||
function BoolToString(value)
|
||||
if value==true then return 1 end
|
||||
return 0
|
||||
--[[
|
||||
General stuff
|
||||
]]
|
||||
-- Returns Handy plugin version number
|
||||
function GetHandyVersion()
|
||||
return HANDY_VERSION
|
||||
end
|
||||
-- Checks if handy is in proper version
|
||||
function CheckForRequiedVersion(IN_version)
|
||||
if (IN_version > HANDY_VERSION) then return false end
|
||||
return true
|
||||
end
|
||||
--[[
|
||||
MCS-specific _functions and nasty hacks :D
|
||||
]]
|
||||
-- There's a "GetChestHeight" function inside source code, but it's not lua-exported
|
||||
function GetChestHeightCheat(IN_chest)
|
||||
if (IN_chest:GetSlot(28) == nil) then -- this means we're trying to get double chest slot and FAIL
|
||||
LOGWARN("HANDY: single chest checked")
|
||||
return 3
|
||||
end
|
||||
LOGWARN("HANDY: double chest checked")
|
||||
return 6
|
||||
end
|
||||
-- Those two checks how many items of given IN_itemID chest and player have, and how much they could fit inside them
|
||||
function ReadChestForItem(IN_chest, IN_itemID)
|
||||
local _items_found = 0
|
||||
local _free_space = 0
|
||||
-- stalk through chest slots...
|
||||
local _slot_counter = 0
|
||||
local _slot_item
|
||||
local _item_max_stack = GetItemMaxStack(IN_itemID)
|
||||
while true do
|
||||
_slot_item = IN_chest:GetSlot(_slot_counter)
|
||||
if (_slot_item ~= nil) then
|
||||
if (_slot_item.m_ItemID == IN_itemID) then
|
||||
_items_found = _items_found + _slot_item.m_ItemCount
|
||||
_free_space = _free_space + (_item_max_stack - _slot_item.m_ItemCount)
|
||||
end
|
||||
if (_slot_item:IsEmpty() == true) then
|
||||
_free_space = _free_space + _item_max_stack
|
||||
end
|
||||
end
|
||||
_slot_counter = _slot_counter + 1
|
||||
if (_slot_counter == CHEST_WIDTH*GetChestHeightCheat(IN_chest)) then
|
||||
break
|
||||
end
|
||||
end
|
||||
return _items_found, _free_space
|
||||
end
|
||||
function ReadPlayerForItem(IN_player, IN_itemID)
|
||||
local _items_found = 0
|
||||
local _free_space = 0
|
||||
-- stalk through IN_player inventory slots...
|
||||
local _slot_counter = 9
|
||||
if (ItemIsArmor(IN_itemID) == true) then _slot_counter = 5 end
|
||||
local _slot_item
|
||||
local _item_max_stack = GetItemMaxStack(IN_itemID)
|
||||
while true do
|
||||
_slot_item = IN_player:GetInventory():GetSlot(_slot_counter)
|
||||
if (_slot_item ~= nil) then
|
||||
if (_slot_item.m_ItemID == IN_itemID) then
|
||||
_items_found = _items_found + _slot_item.m_ItemCount
|
||||
_free_space = _free_space + (_item_max_stack - _slot_item.m_ItemCount)
|
||||
end
|
||||
if (_slot_item:IsEmpty() == true) then
|
||||
_free_space = _free_space + _item_max_stack
|
||||
end
|
||||
end
|
||||
_slot_counter = _slot_counter + 1
|
||||
if (_slot_counter == 45) then
|
||||
break
|
||||
end
|
||||
end
|
||||
return _items_found, _free_space
|
||||
end
|
||||
-- Following functions are for chest-related operations (since noone was bothered writing them in MCS code)
|
||||
-- BEWARE! Those assume you did checked if chest has items/space in it!
|
||||
function TakeItemsFromChest(IN_chest, IN_itemID, IN_ammount) -- UNSAFE! CHECK FOR ITEMS FIRST!!
|
||||
-- stalk through chest slots...
|
||||
local _slot_counter = 0
|
||||
local _slot_item
|
||||
local _take_count = IN_ammount
|
||||
while true do
|
||||
_slot_item = IN_chest:GetSlot(_slot_counter)
|
||||
if (_slot_item ~= nil) then
|
||||
if (_slot_item.m_ItemID == IN_itemID) then
|
||||
-- assuming player have enought money
|
||||
if (_take_count > 0) then
|
||||
if (_take_count > _slot_item.m_ItemCount) then
|
||||
_take_count = _take_count - _slot_item.m_ItemCount
|
||||
IN_chest:SetSlot(_slot_counter, cItem()) -- a bit hacky, can't make cItem:Clear() work(
|
||||
else
|
||||
local _left_count = _slot_item.m_ItemCount - _take_count
|
||||
IN_chest:SetSlot(_slot_counter, cItem(_slot_item.m_ItemID, _left_count)) -- a bit hacky
|
||||
_take_count = 0
|
||||
end
|
||||
end
|
||||
if (_take_count == 0) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
_slot_counter = _slot_counter + 1
|
||||
if (_slot_counter == CHEST_WIDTH*GetChestHeightCheat(IN_chest)) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
function PutItemsToChest(IN_chest, IN_itemID, IN_ammount) -- UNSAFE! CHECK FOR SPACE FIRST!!
|
||||
-- stalk through chest slots...
|
||||
local _slot_counter = 0
|
||||
local _slot_item
|
||||
local _put_count = IN_ammount
|
||||
local _max_stack = GetItemMaxStack(IN_itemID)
|
||||
while true do
|
||||
_slot_item = IN_chest:GetSlot(_slot_counter)
|
||||
local _portion = 0
|
||||
local _ammount_to_set = 0
|
||||
if (_slot_item ~= nil) then
|
||||
if (_slot_item:IsEmpty() == true) then
|
||||
_portion = math.min(_max_stack, _put_count)
|
||||
_ammount_to_set = _portion
|
||||
else
|
||||
if (_slot_item.m_ItemID == IN_itemID) then
|
||||
-- choose between how much we need to put and how much free space left
|
||||
_portion = math.min(_put_count, _max_stack - _slot_item.m_ItemCount)
|
||||
_ammount_to_set = _slot_item.m_ItemCount + _portion
|
||||
end
|
||||
end
|
||||
end
|
||||
IN_chest:SetSlot(_slot_counter, cItem(IN_itemID, _ammount_to_set)) -- we add max stack to chest
|
||||
_put_count = _put_count - _portion
|
||||
if (_put_count == 0) then break end
|
||||
_slot_counter = _slot_counter + 1
|
||||
if (_slot_counter == CHEST_WIDTH*GetChestHeightCheat(IN_chest)) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Similar to chest-related.
|
||||
function TakeItemsFromPlayer(IN_player, IN_itemID, IN_ammount) -- UNSAFE! CHECK FIRST!
|
||||
local _put_count = IN_ammount
|
||||
local _max_stack = GetItemMaxStack(IN_itemID)
|
||||
while true do
|
||||
local _portion = math.min(_max_stack, _put_count)
|
||||
IN_player:GetInventory():RemoveItem(cItem(IN_itemID, _portion))
|
||||
_put_count = _put_count - _portion
|
||||
if (_put_count == 0) then break end
|
||||
end
|
||||
end
|
||||
function GiveItemsToPlayer(IN_player, IN_itemID, IN_ammount) -- UNSAFE! CHECK FIRST!
|
||||
local _put_count = IN_ammount
|
||||
local _max_stack = GetItemMaxStack(IN_itemID)
|
||||
while true do
|
||||
local _portion = math.min(_max_stack, _put_count)
|
||||
IN_player:GetInventory():AddItem(cItem(IN_itemID, _portion))
|
||||
_put_count = _put_count - _portion
|
||||
if (_put_count == 0) then break end
|
||||
end
|
||||
end
|
||||
-- This function returns item max stack for a given itemID. It uses vanilla max stack size, and uses several non-common items notations;
|
||||
-- Those are:
|
||||
-- oneonerecord (because aparently 11record wasn't the best idea in lua scripting application)
|
||||
-- carrotonastick (because it wasn't added to items.txt yet)
|
||||
-- waitrecord (for same reason)
|
||||
-- Feel free to ignore the difference, or to add those to items.txt
|
||||
function GetItemMaxStack(IN_itemID)
|
||||
local _result = 64
|
||||
-- Tools and swords
|
||||
if (IN_itemID == woodensword) then _result = 1 end
|
||||
if (IN_itemID == woodenshovel) then _result = 1 end
|
||||
if (IN_itemID == woodenpickaxe) then _result = 1 end
|
||||
if (IN_itemID == woodenaxe) then _result = 1 end
|
||||
if (IN_itemID == woodenhoe) then _result = 1 end
|
||||
if (IN_itemID == stonesword) then _result = 1 end
|
||||
if (IN_itemID == stoneshovel) then _result = 1 end
|
||||
if (IN_itemID == stonepickaxe) then _result = 1 end
|
||||
if (IN_itemID == stoneaxe) then _result = 1 end
|
||||
if (IN_itemID == stonehoe) then _result = 1 end
|
||||
if (IN_itemID == ironsword) then _result = 1 end
|
||||
if (IN_itemID == ironshovel) then _result = 1 end
|
||||
if (IN_itemID == ironpickaxe) then _result = 1 end
|
||||
if (IN_itemID == ironaxe) then _result = 1 end
|
||||
if (IN_itemID == ironhoe) then _result = 1 end
|
||||
if (IN_itemID == diamondsword) then _result = 1 end
|
||||
if (IN_itemID == diamondshovel) then _result = 1 end
|
||||
if (IN_itemID == diamondpickaxe) then _result = 1 end
|
||||
if (IN_itemID == diamondaxe) then _result = 1 end
|
||||
if (IN_itemID == diamondhoe) then _result = 1 end
|
||||
if (IN_itemID == goldensword) then _result = 1 end
|
||||
if (IN_itemID == goldenshovel) then _result = 1 end
|
||||
if (IN_itemID == goldenpickaxe) then _result = 1 end
|
||||
if (IN_itemID == goldenaxe) then _result = 1 end
|
||||
if (IN_itemID == goldenhoe) then _result = 1 end
|
||||
|
||||
if (IN_itemID == flintandsteel) then _result = 1 end
|
||||
if (IN_itemID == bow) then _result = 1 end
|
||||
if (IN_itemID == sign) then _result = 16 end
|
||||
if (IN_itemID == woodendoor) then _result = 1 end
|
||||
if (IN_itemID == irondoor) then _result = 1 end
|
||||
if (IN_itemID == cake) then _result = 1 end
|
||||
if (IN_itemID == cauldron) then _result = 1 end
|
||||
if (IN_itemID == mushroomstew) then _result = 1 end
|
||||
if (IN_itemID == painting) then _result = 1 end
|
||||
if (IN_itemID == bucket) then _result = 16 end
|
||||
if (IN_itemID == waterbucket) then _result = 1 end
|
||||
if (IN_itemID == lavabucket) then _result = 1 end
|
||||
if (IN_itemID == minecart) then _result = 1 end
|
||||
if (IN_itemID == saddle) then _result = 1 end
|
||||
if (IN_itemID == snowball) then _result = 16 end
|
||||
if (IN_itemID == boat) then _result = 1 end
|
||||
if (IN_itemID == milkbucket) then _result = 1 end
|
||||
if (IN_itemID == storageminecart) then _result = 1 end
|
||||
if (IN_itemID == poweredminecart) then _result = 1 end
|
||||
if (IN_itemID == egg) then _result = 16 end
|
||||
if (IN_itemID == fishingrod) then _result = 1 end
|
||||
if (IN_itemID == bed) then _result = 1 end
|
||||
if (IN_itemID == map) then _result = 1 end
|
||||
if (IN_itemID == shears) then _result = 1 end
|
||||
if (IN_itemID == enderpearl) then _result = 16 end
|
||||
if (IN_itemID == potion) then _result = 1 end
|
||||
if (IN_itemID == spawnegg) then _result = 1 end
|
||||
if (IN_itemID == bookandquill) then _result = 1 end
|
||||
if (IN_itemID == writtenbook) then _result = 1 end
|
||||
if (IN_itemID == carrotonastick) then _result = 1 end
|
||||
|
||||
if (IN_itemID == goldrecord) then _result = 1 end
|
||||
if (IN_itemID == greenrecord) then _result = 1 end
|
||||
if (IN_itemID == blocksrecord) then _result = 1 end
|
||||
if (IN_itemID == chirprecord) then _result = 1 end
|
||||
if (IN_itemID == farrecord) then _result = 1 end
|
||||
if (IN_itemID == mallrecord) then _result = 1 end
|
||||
if (IN_itemID == mellohirecord) then _result = 1 end
|
||||
if (IN_itemID == stalrecord) then _result = 1 end
|
||||
if (IN_itemID == stradrecord) then _result = 1 end
|
||||
if (IN_itemID == wardrecord) then _result = 1 end
|
||||
if (IN_itemID == oneonerecord) then _result = 1 end
|
||||
if (IN_itemID == waitrecord) then _result = 1 end
|
||||
|
||||
--if (IN_itemID == xxxxxxxxx) then _result = 1 end
|
||||
|
||||
if (IN_itemID == leatherhelmet) then _result = 1 end
|
||||
if (IN_itemID == leatherchestplate) then _result = 1 end
|
||||
if (IN_itemID == leatherpants) then _result = 1 end
|
||||
if (IN_itemID == leatherboots) then _result = 1 end
|
||||
|
||||
if (IN_itemID == chainmailhelmet) then _result = 1 end
|
||||
if (IN_itemID == chainmailchestplate) then _result = 1 end
|
||||
if (IN_itemID == chainmailpants) then _result = 1 end
|
||||
if (IN_itemID == chainmailboots) then _result = 1 end
|
||||
|
||||
if (IN_itemID == ironhelmet) then _result = 1 end
|
||||
if (IN_itemID == ironchestplate) then _result = 1 end
|
||||
if (IN_itemID == ironpants) then _result = 1 end
|
||||
if (IN_itemID == ironboots) then _result = 1 end
|
||||
|
||||
if (IN_itemID == diamondhelmet) then _result = 1 end
|
||||
if (IN_itemID == diamondchestplate) then _result = 1 end
|
||||
if (IN_itemID == diamondpants) then _result = 1 end
|
||||
if (IN_itemID == diamondboots) then _result = 1 end
|
||||
|
||||
if (IN_itemID == goldenhelmet) then _result = 1 end
|
||||
if (IN_itemID == goldenchestplate) then _result = 1 end
|
||||
if (IN_itemID == goldenpants) then _result = 1 end
|
||||
if (IN_itemID == goldenboots) then _result = 1 end
|
||||
return _result
|
||||
end
|
||||
function ItemIsArmor(IN_itemID)
|
||||
local _result = false
|
||||
if (IN_itemID == leatherhelmet) then _result = true end
|
||||
if (IN_itemID == leatherchestplate) then _result = true end
|
||||
if (IN_itemID == leatherpants) then _result = true end
|
||||
if (IN_itemID == leatherboots) then _result = true end
|
||||
|
||||
if (IN_itemID == chainmailhelmet) then _result = true end
|
||||
if (IN_itemID == chainmailchestplate) then _result = true end
|
||||
if (IN_itemID == chainmailpants) then _result = true end
|
||||
if (IN_itemID == chainmailboots) then _result = true end
|
||||
|
||||
if (IN_itemID == ironhelmet) then _result = true end
|
||||
if (IN_itemID == ironchestplate) then _result = true end
|
||||
if (IN_itemID == ironpants) then _result = true end
|
||||
if (IN_itemID == ironboots) then _result = true end
|
||||
|
||||
if (IN_itemID == diamondhelmet) then _result = true end
|
||||
if (IN_itemID == diamondchestplate) then _result = true end
|
||||
if (IN_itemID == diamondpants) then _result = true end
|
||||
if (IN_itemID == diamondboots) then _result = true end
|
||||
|
||||
if (IN_itemID == goldenhelmet) then _result = true end
|
||||
if (IN_itemID == goldenchestplate) then _result = true end
|
||||
if (IN_itemID == goldenpants) then _result = true end
|
||||
if (IN_itemID == goldenboots) then _result = true end
|
||||
return _result
|
||||
end
|
||||
-- Returns full-length playername for a short name (usefull for parsing commands)
|
||||
function GetExactPlayername(IN_playername)
|
||||
local _result = IN_playername
|
||||
local function SetProcessingPlayername(IN_player)
|
||||
_result = IN_player:GetName()
|
||||
end
|
||||
cRoot:Get():FindAndDoWithPlayer(IN_playername, SetProcessingPlayername)
|
||||
return _result
|
||||
end
|
||||
function GetPlayerByName(IN_playername)
|
||||
local _player
|
||||
local PlayerSetter = function (Player)
|
||||
_player = Player
|
||||
end
|
||||
cRoot:Get():FindAndDoWithPlayer(IN_playername, PlayerSetter)
|
||||
return _player
|
||||
end
|
||||
--[[
|
||||
Not-so-usual math _functions
|
||||
]]
|
||||
-- Rounds floating point number. Because lua guys think this function doesn't deserve to be presented in lua's math
|
||||
function round(IN_x)
|
||||
if (IN_x%2 ~= 0.5) then
|
||||
return math.floor(IN_x+0.5)
|
||||
end
|
||||
return IN_x-0.5
|
||||
end
|
||||
--[[
|
||||
Functions I use for filework and stringswork
|
||||
]]
|
||||
function PluralString(IN_value, IN_singular_string, IN_plural_string)
|
||||
local _value_string = tostring(IN_value)
|
||||
if (_value_string[#_value_string] == "1") then
|
||||
return IN_singular_string
|
||||
end
|
||||
return IN_plural_string
|
||||
end
|
||||
function PluralItemName(IN_itemID, IN_ammount) -- BEWARE! TEMPORAL SOLUTION THERE! :D
|
||||
local _value_string = tostring(IN_value)
|
||||
local _name = ""
|
||||
if (_value_string[#_value_string] == "1") then
|
||||
-- singular names
|
||||
_name = ItemTypeToString(IN_itemID)
|
||||
else
|
||||
-- plural names
|
||||
_name = ItemTypeToString(IN_itemID).."s"
|
||||
end
|
||||
return _name
|
||||
end
|
||||
-- for filewriting purposes. 0 = false, 1 = true
|
||||
function StringToBool(value)
|
||||
if value=="1" then return true end
|
||||
return false
|
||||
end
|
||||
-- same, but reversal
|
||||
function BoolToString(value)
|
||||
if value==true then return 1 end
|
||||
return 0
|
||||
end
|
@ -1,404 +1,404 @@
|
||||
|
||||
-- Global variables
|
||||
PLUGIN = {} -- Reference to own plugin object
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function Initialize(Plugin)
|
||||
PLUGIN = Plugin
|
||||
|
||||
Plugin:SetName("HookNotify");
|
||||
Plugin:SetVersion(1);
|
||||
|
||||
PluginManager = cPluginManager:Get();
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_BLOCK_TO_PICKUPS);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHAT);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_AVAILABLE);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATED);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_UNLOADED);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_UNLOADING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_COLLECTING_PICKUP);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CRAFTING_NO_RECIPE);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_DISCONNECT);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_EXECUTE_COMMAND);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_HANDSHAKE);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_KILLING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_LOGIN);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_BREAKING_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_BROKEN_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_EATING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_JOINED);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_LEFT_CLICK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_MOVING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_PLACED_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_PLACING_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_RIGHT_CLICK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_SHOOTING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_SPAWNED);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_TOSSING_ITEM);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USED_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USED_ITEM);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USING_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USING_ITEM);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_POST_CRAFTING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PRE_CRAFTING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_TAKE_DAMAGE);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_UPDATED_SIGN);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_UPDATING_SIGN);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_WEATHER_CHANGED);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_WEATHER_CHANGING);
|
||||
|
||||
LOGINFO("HookNotify plugin is installed, beware, the log output may be quite large!");
|
||||
LOGINFO("You want this plugin enabled only when developing another plugin, not for regular gameplay.");
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function LogHook(FnName, ...)
|
||||
LOG(FnName .. "(");
|
||||
for i, v in ipairs(arg) do
|
||||
local vt = tostring(v);
|
||||
local TypeString = type(v);
|
||||
if (type(v) == "userdata") then
|
||||
TypeString = tolua.type(v);
|
||||
end;
|
||||
LOG(" " .. tostring(i) .. ": " .. TypeString .. ": " .. tostring(v));
|
||||
end
|
||||
LOG(")");
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnBlockToPickups(...)
|
||||
LogHook("OnBlockToPickups", unpack(arg));
|
||||
local World, Digger, BlockX, BlockY, BlockZ, BlockType, BlockMeta, Pickups = unpack(arg);
|
||||
if (Pickups ~= nil) then
|
||||
local Name = "NULL";
|
||||
if (Digger ~= nil) then
|
||||
Name = Digger:GetName()
|
||||
end
|
||||
LOG("Got cItems from " .. Name .. ", trying to manipulate them.");
|
||||
Pickups:Add(cItem:new(E_ITEM_DIAMOND_SHOVEL, 1));
|
||||
LOG("Current size: " .. Pickups:Size());
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChat(...)
|
||||
LogHook("OnChat", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChunkAvailable(...)
|
||||
LogHook("OnChunkAvailable", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChunkGenerated(...)
|
||||
LogHook("OnChunkGenerated", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChunkGenerating(...)
|
||||
LogHook("OnChunkGenerating", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChunkUnloaded(...)
|
||||
LogHook("OnChunkUnloaded", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChunkUnloading(...)
|
||||
LogHook("OnChunkUnloading", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsingItem(...)
|
||||
LogHook("OnPlayerUsingItem", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnCollectingPickup(...)
|
||||
LogHook("OnCollectingPickup", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
function OnCraftingNoRecipe(...)
|
||||
LogHook("OnCraftingNoRecipe", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnDisconnect(...)
|
||||
LogHook("OnDisconnect", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnExecuteCommand(...)
|
||||
LogHook("OnExecuteCommand", unpack(arg));
|
||||
|
||||
-- For some reason logging doesn't work for this callback, so list some stuff manually to verify:
|
||||
LOG("arg1 type: " .. type(arg[1]));
|
||||
if (arg[1] ~= nil) then
|
||||
LOG("Player name: " .. arg[1]:GetName());
|
||||
end
|
||||
LOG("Command: " .. arg[2][1]);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnHandshake(...)
|
||||
LogHook("OnHandshake", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnKilling(...)
|
||||
LogHook("OnKilling", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnLogin(...)
|
||||
LogHook("OnLogin", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerBreakingBlock(...)
|
||||
LogHook("OnPlayerBreakingBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerBrokenBlock(...)
|
||||
LogHook("OnPlayerBrokenBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerEating(...)
|
||||
LogHook("OnPlayerEating", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerJoined(...)
|
||||
LogHook("OnPlayerJoined", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerLeftClick(...)
|
||||
LogHook("OnPlayerLeftClick", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerMoving(...)
|
||||
LogHook("OnPlayerMoving", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerPlacedBlock(...)
|
||||
LogHook("OnPlayerPlacedBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerPlacingBlock(...)
|
||||
LogHook("OnPlayerPlacingBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerRightClick(...)
|
||||
LogHook("OnPlayerRightClick", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerShooting(...)
|
||||
LogHook("OnPlayerShooting", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerSpawned(...)
|
||||
LogHook("OnPlayerSpawned", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerTossingItem(...)
|
||||
LogHook("OnPlayerTossingItem", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsedBlock(...)
|
||||
LogHook("OnPlayerUsedBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsedItem(...)
|
||||
LogHook("OnPlayerUsedItem", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsingBlock(...)
|
||||
LogHook("OnPlayerUsingBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsingItem(...)
|
||||
LogHook("OnPlayerUsingItem", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPostCrafting(...)
|
||||
LogHook("OnPostCrafting", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPreCrafting(...)
|
||||
LogHook("OnPreCrafting", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnUpdatedSign(...)
|
||||
LogHook("OnUpdatedSign", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnUpdatingSign(...)
|
||||
LogHook("OnUpdatingSign", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnWeatherChanged(...)
|
||||
LogHook("OnWeatherChanged", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnWeatherChanging(...)
|
||||
LogHook("OnWeatherChanging", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Special handling for OnTakeDamage to print the contents of TDI:
|
||||
|
||||
function OnTakeDamage(Receiver, TDI)
|
||||
-- Receiver is cPawn
|
||||
-- TDI is TakeDamageInfo
|
||||
|
||||
LOG("OnTakeDamage(): " .. Receiver:GetClass() .. " was dealt RawDamage " .. TDI.RawDamage .. ", FinalDamage " .. TDI.FinalDamage .. " (that is, " .. (TDI.RawDamage - TDI.FinalDamage) .. " HPs covered by armor)");
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- Global variables
|
||||
PLUGIN = {} -- Reference to own plugin object
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function Initialize(Plugin)
|
||||
PLUGIN = Plugin
|
||||
|
||||
Plugin:SetName("HookNotify");
|
||||
Plugin:SetVersion(1);
|
||||
|
||||
PluginManager = cPluginManager:Get();
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_BLOCK_TO_PICKUPS);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHAT);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_AVAILABLE);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATED);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_UNLOADED);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_UNLOADING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_COLLECTING_PICKUP);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CRAFTING_NO_RECIPE);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_DISCONNECT);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_EXECUTE_COMMAND);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_HANDSHAKE);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_KILLING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_LOGIN);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_BREAKING_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_BROKEN_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_EATING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_JOINED);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_LEFT_CLICK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_MOVING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_PLACED_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_PLACING_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_RIGHT_CLICK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_SHOOTING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_SPAWNED);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_TOSSING_ITEM);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USED_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USED_ITEM);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USING_BLOCK);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USING_ITEM);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_POST_CRAFTING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PRE_CRAFTING);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_TAKE_DAMAGE);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_UPDATED_SIGN);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_UPDATING_SIGN);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_WEATHER_CHANGED);
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_WEATHER_CHANGING);
|
||||
|
||||
LOGINFO("HookNotify plugin is installed, beware, the log output may be quite large!");
|
||||
LOGINFO("You want this plugin enabled only when developing another plugin, not for regular gameplay.");
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function LogHook(FnName, ...)
|
||||
LOG(FnName .. "(");
|
||||
for i, v in ipairs(arg) do
|
||||
local vt = tostring(v);
|
||||
local TypeString = type(v);
|
||||
if (type(v) == "userdata") then
|
||||
TypeString = tolua.type(v);
|
||||
end;
|
||||
LOG(" " .. tostring(i) .. ": " .. TypeString .. ": " .. tostring(v));
|
||||
end
|
||||
LOG(")");
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnBlockToPickups(...)
|
||||
LogHook("OnBlockToPickups", unpack(arg));
|
||||
local World, Digger, BlockX, BlockY, BlockZ, BlockType, BlockMeta, Pickups = unpack(arg);
|
||||
if (Pickups ~= nil) then
|
||||
local Name = "NULL";
|
||||
if (Digger ~= nil) then
|
||||
Name = Digger:GetName()
|
||||
end
|
||||
LOG("Got cItems from " .. Name .. ", trying to manipulate them.");
|
||||
Pickups:Add(cItem:new(E_ITEM_DIAMOND_SHOVEL, 1));
|
||||
LOG("Current size: " .. Pickups:Size());
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChat(...)
|
||||
LogHook("OnChat", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChunkAvailable(...)
|
||||
LogHook("OnChunkAvailable", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChunkGenerated(...)
|
||||
LogHook("OnChunkGenerated", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChunkGenerating(...)
|
||||
LogHook("OnChunkGenerating", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChunkUnloaded(...)
|
||||
LogHook("OnChunkUnloaded", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChunkUnloading(...)
|
||||
LogHook("OnChunkUnloading", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsingItem(...)
|
||||
LogHook("OnPlayerUsingItem", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnCollectingPickup(...)
|
||||
LogHook("OnCollectingPickup", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
function OnCraftingNoRecipe(...)
|
||||
LogHook("OnCraftingNoRecipe", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnDisconnect(...)
|
||||
LogHook("OnDisconnect", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnExecuteCommand(...)
|
||||
LogHook("OnExecuteCommand", unpack(arg));
|
||||
|
||||
-- For some reason logging doesn't work for this callback, so list some stuff manually to verify:
|
||||
LOG("arg1 type: " .. type(arg[1]));
|
||||
if (arg[1] ~= nil) then
|
||||
LOG("Player name: " .. arg[1]:GetName());
|
||||
end
|
||||
LOG("Command: " .. arg[2][1]);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnHandshake(...)
|
||||
LogHook("OnHandshake", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnKilling(...)
|
||||
LogHook("OnKilling", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnLogin(...)
|
||||
LogHook("OnLogin", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerBreakingBlock(...)
|
||||
LogHook("OnPlayerBreakingBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerBrokenBlock(...)
|
||||
LogHook("OnPlayerBrokenBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerEating(...)
|
||||
LogHook("OnPlayerEating", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerJoined(...)
|
||||
LogHook("OnPlayerJoined", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerLeftClick(...)
|
||||
LogHook("OnPlayerLeftClick", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerMoving(...)
|
||||
LogHook("OnPlayerMoving", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerPlacedBlock(...)
|
||||
LogHook("OnPlayerPlacedBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerPlacingBlock(...)
|
||||
LogHook("OnPlayerPlacingBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerRightClick(...)
|
||||
LogHook("OnPlayerRightClick", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerShooting(...)
|
||||
LogHook("OnPlayerShooting", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerSpawned(...)
|
||||
LogHook("OnPlayerSpawned", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerTossingItem(...)
|
||||
LogHook("OnPlayerTossingItem", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsedBlock(...)
|
||||
LogHook("OnPlayerUsedBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsedItem(...)
|
||||
LogHook("OnPlayerUsedItem", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsingBlock(...)
|
||||
LogHook("OnPlayerUsingBlock", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerUsingItem(...)
|
||||
LogHook("OnPlayerUsingItem", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPostCrafting(...)
|
||||
LogHook("OnPostCrafting", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPreCrafting(...)
|
||||
LogHook("OnPreCrafting", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnUpdatedSign(...)
|
||||
LogHook("OnUpdatedSign", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnUpdatingSign(...)
|
||||
LogHook("OnUpdatingSign", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnWeatherChanged(...)
|
||||
LogHook("OnWeatherChanged", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnWeatherChanging(...)
|
||||
LogHook("OnWeatherChanging", unpack(arg));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Special handling for OnTakeDamage to print the contents of TDI:
|
||||
|
||||
function OnTakeDamage(Receiver, TDI)
|
||||
-- Receiver is cPawn
|
||||
-- TDI is TakeDamageInfo
|
||||
|
||||
LOG("OnTakeDamage(): " .. Receiver:GetClass() .. " was dealt RawDamage " .. TDI.RawDamage .. ", FinalDamage " .. TDI.FinalDamage .. " (that is, " .. (TDI.RawDamage - TDI.FinalDamage) .. " HPs covered by armor)");
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
@ -1,97 +1,97 @@
|
||||
-- Location object
|
||||
cLocation = {}
|
||||
function cLocation:new( x, y, z )
|
||||
local object = { x = x, y = y, z = z }
|
||||
setmetatable(object, { __index = cLocation })
|
||||
return object
|
||||
end
|
||||
|
||||
-- Offsets
|
||||
cFibers = { }
|
||||
function cFibers:new()
|
||||
local object = {
|
||||
cLocation:new( 2, -1, 2 ),
|
||||
cLocation:new( 2, -1, 1 ),
|
||||
cLocation:new( 2, -1, 0 ),
|
||||
cLocation:new( 2, -1, -1 ),
|
||||
cLocation:new( 2, -1, -2 ),
|
||||
cLocation:new( 1, -1, 2 ),
|
||||
cLocation:new( 1, -1, 1 ),
|
||||
cLocation:new( 1, -1, 0 ),
|
||||
cLocation:new( 1, -1, -1 ),
|
||||
cLocation:new( 1, -1, -2 ),
|
||||
cLocation:new( 0, -1, 2 ),
|
||||
cLocation:new( 0, -1, 1 ),
|
||||
cLocation:new( 0, -1, 0 ),
|
||||
cLocation:new( 0, -1, -1 ),
|
||||
cLocation:new( 0, -1, -2 ),
|
||||
cLocation:new( -1, -1, 2 ),
|
||||
cLocation:new( -1, -1, 1 ),
|
||||
cLocation:new( -1, -1, 0 ),
|
||||
cLocation:new( -1, -1, -1 ),
|
||||
cLocation:new( -1, -1, -2 ),
|
||||
cLocation:new( -2, -1, 2 ),
|
||||
cLocation:new( -2, -1, 1 ),
|
||||
cLocation:new( -2, -1, 0 ),
|
||||
cLocation:new( -2, -1, -1 ),
|
||||
cLocation:new( -2, -1, -2 ),
|
||||
imadeit = false,
|
||||
}
|
||||
setmetatable(object, { __index = cFibers })
|
||||
return object;
|
||||
end
|
||||
|
||||
-- Carpet object
|
||||
cCarpet = {}
|
||||
function cCarpet:new()
|
||||
local object = { Location = cLocation:new(0,0,0),
|
||||
Fibers = cFibers:new(),
|
||||
}
|
||||
setmetatable(object, { __index = cCarpet })
|
||||
return object
|
||||
end
|
||||
|
||||
function cCarpet:remove()
|
||||
local World = cRoot:Get():GetDefaultWorld()
|
||||
for i, fib in ipairs( self.Fibers ) do
|
||||
local x = self.Location.x + fib.x
|
||||
local y = self.Location.y + fib.y
|
||||
local z = self.Location.z + fib.z
|
||||
local BlockID = World:GetBlock( x, y, z )
|
||||
if( fib.imadeit == true and BlockID == E_BLOCK_GLASS ) then
|
||||
World:SetBlock( x, y, z, 0, 0 )
|
||||
fib.imadeit = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cCarpet:draw()
|
||||
local World = cRoot:Get():GetDefaultWorld()
|
||||
for i, fib in ipairs( self.Fibers ) do
|
||||
local x = self.Location.x + fib.x
|
||||
local y = self.Location.y + fib.y
|
||||
local z = self.Location.z + fib.z
|
||||
local BlockID = World:GetBlock( x, y, z )
|
||||
if( BlockID == 0 ) then
|
||||
fib.imadeit = true
|
||||
World:SetBlock( x, y, z, E_BLOCK_GLASS, 0 )
|
||||
else
|
||||
fib.imadeit = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cCarpet:moveTo( NewPos )
|
||||
local x = math.floor( NewPos.x )
|
||||
local y = math.floor( NewPos.y )
|
||||
local z = math.floor( NewPos.z )
|
||||
if( self.Location.x ~= x or self.Location.y ~= y or self.Location.z ~= z ) then
|
||||
self:remove()
|
||||
self.Location = cLocation:new( x, y, z )
|
||||
self:draw()
|
||||
end
|
||||
end
|
||||
|
||||
function cCarpet:getY()
|
||||
return self.Location.y
|
||||
-- Location object
|
||||
cLocation = {}
|
||||
function cLocation:new( x, y, z )
|
||||
local object = { x = x, y = y, z = z }
|
||||
setmetatable(object, { __index = cLocation })
|
||||
return object
|
||||
end
|
||||
|
||||
-- Offsets
|
||||
cFibers = { }
|
||||
function cFibers:new()
|
||||
local object = {
|
||||
cLocation:new( 2, -1, 2 ),
|
||||
cLocation:new( 2, -1, 1 ),
|
||||
cLocation:new( 2, -1, 0 ),
|
||||
cLocation:new( 2, -1, -1 ),
|
||||
cLocation:new( 2, -1, -2 ),
|
||||
cLocation:new( 1, -1, 2 ),
|
||||
cLocation:new( 1, -1, 1 ),
|
||||
cLocation:new( 1, -1, 0 ),
|
||||
cLocation:new( 1, -1, -1 ),
|
||||
cLocation:new( 1, -1, -2 ),
|
||||
cLocation:new( 0, -1, 2 ),
|
||||
cLocation:new( 0, -1, 1 ),
|
||||
cLocation:new( 0, -1, 0 ),
|
||||
cLocation:new( 0, -1, -1 ),
|
||||
cLocation:new( 0, -1, -2 ),
|
||||
cLocation:new( -1, -1, 2 ),
|
||||
cLocation:new( -1, -1, 1 ),
|
||||
cLocation:new( -1, -1, 0 ),
|
||||
cLocation:new( -1, -1, -1 ),
|
||||
cLocation:new( -1, -1, -2 ),
|
||||
cLocation:new( -2, -1, 2 ),
|
||||
cLocation:new( -2, -1, 1 ),
|
||||
cLocation:new( -2, -1, 0 ),
|
||||
cLocation:new( -2, -1, -1 ),
|
||||
cLocation:new( -2, -1, -2 ),
|
||||
imadeit = false,
|
||||
}
|
||||
setmetatable(object, { __index = cFibers })
|
||||
return object;
|
||||
end
|
||||
|
||||
-- Carpet object
|
||||
cCarpet = {}
|
||||
function cCarpet:new()
|
||||
local object = { Location = cLocation:new(0,0,0),
|
||||
Fibers = cFibers:new(),
|
||||
}
|
||||
setmetatable(object, { __index = cCarpet })
|
||||
return object
|
||||
end
|
||||
|
||||
function cCarpet:remove()
|
||||
local World = cRoot:Get():GetDefaultWorld()
|
||||
for i, fib in ipairs( self.Fibers ) do
|
||||
local x = self.Location.x + fib.x
|
||||
local y = self.Location.y + fib.y
|
||||
local z = self.Location.z + fib.z
|
||||
local BlockID = World:GetBlock( x, y, z )
|
||||
if( fib.imadeit == true and BlockID == E_BLOCK_GLASS ) then
|
||||
World:SetBlock( x, y, z, 0, 0 )
|
||||
fib.imadeit = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cCarpet:draw()
|
||||
local World = cRoot:Get():GetDefaultWorld()
|
||||
for i, fib in ipairs( self.Fibers ) do
|
||||
local x = self.Location.x + fib.x
|
||||
local y = self.Location.y + fib.y
|
||||
local z = self.Location.z + fib.z
|
||||
local BlockID = World:GetBlock( x, y, z )
|
||||
if( BlockID == 0 ) then
|
||||
fib.imadeit = true
|
||||
World:SetBlock( x, y, z, E_BLOCK_GLASS, 0 )
|
||||
else
|
||||
fib.imadeit = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cCarpet:moveTo( NewPos )
|
||||
local x = math.floor( NewPos.x )
|
||||
local y = math.floor( NewPos.y )
|
||||
local z = math.floor( NewPos.z )
|
||||
if( self.Location.x ~= x or self.Location.y ~= y or self.Location.z ~= z ) then
|
||||
self:remove()
|
||||
self.Location = cLocation:new( x, y, z )
|
||||
self:draw()
|
||||
end
|
||||
end
|
||||
|
||||
function cCarpet:getY()
|
||||
return self.Location.y
|
||||
end
|
@ -1,322 +1,322 @@
|
||||
|
||||
-- CommandHandlers.lua
|
||||
-- Defines the individual command handlers
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function InitializeCommandHandlers()
|
||||
local PlgMgr = cRoot:Get():GetPluginManager();
|
||||
for idx, Cmd in ipairs(CommandReg()) do
|
||||
PlgMgr:BindCommand(Cmd[2], Cmd[3], Cmd[1], Cmd[4]);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Handles the ProtAdd command
|
||||
function HandleAddArea(a_Split, a_Player)
|
||||
-- Command syntax: ProtAdd username1 [username2] [username3] ...
|
||||
if (#a_Split < 2) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedListOfUsernames);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Get the cuboid that the player had selected
|
||||
local CmdState = GetCommandStateForPlayer(a_Player);
|
||||
if (CmdState == nil) then
|
||||
a_Player:SendMessage(g_Msgs.ErrCmdStateNilAddArea);
|
||||
return true;
|
||||
end
|
||||
local Cuboid = CmdState:GetCurrentCuboid();
|
||||
if (Cuboid == nil) then
|
||||
a_Player:SendMessage(g_Msgs.ErrNoAreaWanded);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Put all allowed players into a table:
|
||||
AllowedNames = {};
|
||||
for i = 2, #a_Split do
|
||||
table.insert(AllowedNames, a_Split[i]);
|
||||
end
|
||||
|
||||
-- Add the area to the storage
|
||||
local AreaID = g_Storage:AddArea(Cuboid, a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames);
|
||||
a_Player:SendMessage(string.format(g_Msgs.AreaAdded, AreaID));
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleAddAreaCoords(a_Split, a_Player)
|
||||
-- Command syntax: ProtAddCoords x1 z1 x2 z2 username1 [username2] [username3] ...
|
||||
if (#a_Split < 6) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedCoordsUsernames);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Convert the coords to a cCuboid
|
||||
local x1, z1 = tonumber(a_Split[2]), tonumber(a_Split[3]);
|
||||
local x2, z2 = tonumber(a_Split[4]), tonumber(a_Split[5]);
|
||||
if ((x1 == nil) or (z1 == nil) or (x2 == nil) or (z2 == nil)) then
|
||||
a_Player:SendMessage(g_Msgs.ErrParseCoords);
|
||||
return true;
|
||||
end
|
||||
local Cuboid = cCuboid(x1, 0, z1, x2, 255, z1);
|
||||
Cuboid:Sort();
|
||||
|
||||
-- Put all allowed players into a table:
|
||||
AllowedNames = {};
|
||||
for i = 6, #a_Split do
|
||||
table.insert(AllowedNames, a_Split[i]);
|
||||
end
|
||||
|
||||
-- Add the area to the storage
|
||||
local AreaID = g_Storage:AddArea(Cuboid, a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames);
|
||||
a_Player:SendMessage(string.format(g_Msgs.AreaAdded, AreaID));
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleAddAreaUser(a_Split, a_Player)
|
||||
-- Command syntax: ProtAddUser AreaID username1 [username2] [username3] ...
|
||||
if (#a_Split < 3) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedAreaIDUsernames);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Put all allowed players into a table:
|
||||
AllowedNames = {};
|
||||
for i = 3, #a_Split do
|
||||
table.insert(AllowedNames, a_Split[i]);
|
||||
end
|
||||
|
||||
-- Add the area to the storage
|
||||
if (not(g_Storage:AddAreaUsers(
|
||||
tonumber(a_Split[2]), a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames))
|
||||
) then
|
||||
LOGWARNING("g_Storage:AddAreaUsers failed");
|
||||
a_Player:SendMessage(g_Msgs.ErrDBFailAddUsers);
|
||||
return true;
|
||||
end
|
||||
if (#AllowedNames == 0) then
|
||||
a_Player:SendMessage(g_Msgs.AllUsersAlreadyAllowed);
|
||||
else
|
||||
a_Player:SendMessage(string.format(g_Msgs.UsersAdded, table.concat(AllowedNames, ", ")));
|
||||
end
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleDelArea(a_Split, a_Player)
|
||||
-- Command syntax: ProtDelArea AreaID
|
||||
if (#a_Split ~= 2) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedAreaID);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Parse the AreaID
|
||||
local AreaID = tonumber(a_Split[2]);
|
||||
if (AreaID == nil) then
|
||||
a_Player:SendMessage(g_Msgs.ErrParseAreaID);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Delete the area
|
||||
g_Storage:DelArea(a_Player:GetWorld():GetName(), AreaID);
|
||||
|
||||
a_Player:SendMessage(string.format(g_Msgs.AreaDeleted, AreaID));
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleGiveWand(a_Split, a_Player)
|
||||
local NumGiven = a_Player:GetInventory():AddItem(cConfig:GetWandItem());
|
||||
if (NumGiven == 1) then
|
||||
a_Player:SendMessage(g_Msgs.WandGiven);
|
||||
else
|
||||
a_Player:SendMessage(g_Msgs.ErrNoSpaceForWand);
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleListAreas(a_Split, a_Player)
|
||||
-- Command syntax: ProtListAreas [x, z]
|
||||
|
||||
local x, z;
|
||||
if (#a_Split == 1) then
|
||||
-- Get the last "wanded" coord
|
||||
local CmdState = GetCommandStateForPlayer(a_Player);
|
||||
if (CmdState == nil) then
|
||||
a_Player:SendMessage(g_Msgs.ErrCmdStateNilListAreas);
|
||||
return true;
|
||||
end
|
||||
x, z = CmdState:GetLastCoords();
|
||||
if ((x == nil) or (z == nil)) then
|
||||
a_Player:SendMessage(g_Msgs.ErrListNotWanded);
|
||||
return true;
|
||||
end
|
||||
elseif (#a_Split == 3) then
|
||||
-- Parse the coords from the command params
|
||||
x = tonumber(a_Split[2]);
|
||||
z = tonumber(a_Split[3]);
|
||||
if ((x == nil) or (z == nil)) then
|
||||
a_Player:SendMessage(g_Msgs.ErrParseCoordsListAreas);
|
||||
return true;
|
||||
end
|
||||
else
|
||||
-- Wrong number of params, report back to the user
|
||||
a_Player:SendMessage(g_Msgs.ErrSyntaxErrorListAreas);
|
||||
return true;
|
||||
end
|
||||
|
||||
a_Player:SendMessage(string.format(g_Msgs.ListAreasHeader, x, z));
|
||||
|
||||
-- List areas intersecting the coords
|
||||
local PlayerName = a_Player:GetName();
|
||||
local WorldName = a_Player:GetWorld():GetName();
|
||||
g_Storage:ForEachArea(x, z, WorldName,
|
||||
function(AreaID, MinX, MinZ, MaxX, MaxZ, CreatorName)
|
||||
local Coords = string.format("%s: {%d, %d} - {%d, %d} ", AreaID, MinX, MinZ, MaxX, MaxZ);
|
||||
local Allowance;
|
||||
if (g_Storage:IsAreaAllowed(AreaID, PlayerName, WorldName)) then
|
||||
Allowance = g_Msgs.AreaAllowed;
|
||||
else
|
||||
Allowance = g_Msgs.AreaNotAllowed;
|
||||
end
|
||||
a_Player:SendMessage(string.format(g_Msgs.ListAreasRow, Coords, Allowance, CreatorName));
|
||||
end
|
||||
);
|
||||
|
||||
a_Player:SendMessage(g_Msgs.ListAreasFooter);
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Lists all allowed users for a particular area
|
||||
function HandleListUsers(a_Split, a_Player)
|
||||
-- Command syntax: ProtListUsers AreaID
|
||||
if (#a_Split ~= 2) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedAreaID);
|
||||
end
|
||||
|
||||
-- Get the general info about the area
|
||||
local AreaID = a_Split[2];
|
||||
local WorldName = a_Player:GetWorld():GetName();
|
||||
local MinX, MinZ, MaxX, MaxZ, CreatorName = g_Storage:GetArea(AreaID, WorldName);
|
||||
if (MinX == nil) then
|
||||
a_Player:SendMessage(string.format(g_Msgs.ErrNoSuchArea, AreaID));
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Send the header
|
||||
a_Player:SendMessage(string.format(g_Msgs.ListUsersHeader, AreaID, MinX, MinZ, MaxX, MaxZ, CreatorName));
|
||||
|
||||
-- List and count the allowed users
|
||||
local NumUsers = 0;
|
||||
g_Storage:ForEachUserInArea(AreaID, WorldName,
|
||||
function(UserName)
|
||||
a_Player:SendMessage(string.format(g_Msgs.ListUsersRow, UserName));
|
||||
NumUsers = NumUsers + 1;
|
||||
end
|
||||
);
|
||||
|
||||
-- Send the footer
|
||||
a_Player:SendMessage(string.format(g_Msgs.ListUsersFooter, AreaID, NumUsers));
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleRemoveUser(a_Split, a_Player)
|
||||
-- Command syntax: ProtRemUser AreaID UserName
|
||||
if (#a_Split ~= 3) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedAreaIDUserName);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Parse the AreaID
|
||||
local AreaID = tonumber(a_Split[2]);
|
||||
if (AreaID == nil) then
|
||||
a_Player:SendMessage(g_Msgs.ErrParseAreaID);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Remove the user from the DB
|
||||
local UserName = a_Split[3];
|
||||
g_Storage:RemoveUser(AreaID, UserName, a_Player:GetWorld():GetName());
|
||||
|
||||
-- Send confirmation
|
||||
a_Player:SendMessage(string.format(g_Msgs.RemovedUser, UserName, AreaID));
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleRemoveUserAll(a_Split, a_Player)
|
||||
-- Command syntax: ProtRemUserAll UserName
|
||||
if (#a_Split ~= 2) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedUserName);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Remove the user from the DB
|
||||
g_Storage:RemoveUserAll(a_Split[2], a_Player:GetWorld():GetName());
|
||||
|
||||
-- Send confirmation
|
||||
a_Player:SendMessage(string.format(g_Msgs.RemovedUserAll, UserName));
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- CommandHandlers.lua
|
||||
-- Defines the individual command handlers
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function InitializeCommandHandlers()
|
||||
local PlgMgr = cRoot:Get():GetPluginManager();
|
||||
for idx, Cmd in ipairs(CommandReg()) do
|
||||
PlgMgr:BindCommand(Cmd[2], Cmd[3], Cmd[1], Cmd[4]);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Handles the ProtAdd command
|
||||
function HandleAddArea(a_Split, a_Player)
|
||||
-- Command syntax: ProtAdd username1 [username2] [username3] ...
|
||||
if (#a_Split < 2) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedListOfUsernames);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Get the cuboid that the player had selected
|
||||
local CmdState = GetCommandStateForPlayer(a_Player);
|
||||
if (CmdState == nil) then
|
||||
a_Player:SendMessage(g_Msgs.ErrCmdStateNilAddArea);
|
||||
return true;
|
||||
end
|
||||
local Cuboid = CmdState:GetCurrentCuboid();
|
||||
if (Cuboid == nil) then
|
||||
a_Player:SendMessage(g_Msgs.ErrNoAreaWanded);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Put all allowed players into a table:
|
||||
AllowedNames = {};
|
||||
for i = 2, #a_Split do
|
||||
table.insert(AllowedNames, a_Split[i]);
|
||||
end
|
||||
|
||||
-- Add the area to the storage
|
||||
local AreaID = g_Storage:AddArea(Cuboid, a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames);
|
||||
a_Player:SendMessage(string.format(g_Msgs.AreaAdded, AreaID));
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleAddAreaCoords(a_Split, a_Player)
|
||||
-- Command syntax: ProtAddCoords x1 z1 x2 z2 username1 [username2] [username3] ...
|
||||
if (#a_Split < 6) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedCoordsUsernames);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Convert the coords to a cCuboid
|
||||
local x1, z1 = tonumber(a_Split[2]), tonumber(a_Split[3]);
|
||||
local x2, z2 = tonumber(a_Split[4]), tonumber(a_Split[5]);
|
||||
if ((x1 == nil) or (z1 == nil) or (x2 == nil) or (z2 == nil)) then
|
||||
a_Player:SendMessage(g_Msgs.ErrParseCoords);
|
||||
return true;
|
||||
end
|
||||
local Cuboid = cCuboid(x1, 0, z1, x2, 255, z1);
|
||||
Cuboid:Sort();
|
||||
|
||||
-- Put all allowed players into a table:
|
||||
AllowedNames = {};
|
||||
for i = 6, #a_Split do
|
||||
table.insert(AllowedNames, a_Split[i]);
|
||||
end
|
||||
|
||||
-- Add the area to the storage
|
||||
local AreaID = g_Storage:AddArea(Cuboid, a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames);
|
||||
a_Player:SendMessage(string.format(g_Msgs.AreaAdded, AreaID));
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleAddAreaUser(a_Split, a_Player)
|
||||
-- Command syntax: ProtAddUser AreaID username1 [username2] [username3] ...
|
||||
if (#a_Split < 3) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedAreaIDUsernames);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Put all allowed players into a table:
|
||||
AllowedNames = {};
|
||||
for i = 3, #a_Split do
|
||||
table.insert(AllowedNames, a_Split[i]);
|
||||
end
|
||||
|
||||
-- Add the area to the storage
|
||||
if (not(g_Storage:AddAreaUsers(
|
||||
tonumber(a_Split[2]), a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames))
|
||||
) then
|
||||
LOGWARNING("g_Storage:AddAreaUsers failed");
|
||||
a_Player:SendMessage(g_Msgs.ErrDBFailAddUsers);
|
||||
return true;
|
||||
end
|
||||
if (#AllowedNames == 0) then
|
||||
a_Player:SendMessage(g_Msgs.AllUsersAlreadyAllowed);
|
||||
else
|
||||
a_Player:SendMessage(string.format(g_Msgs.UsersAdded, table.concat(AllowedNames, ", ")));
|
||||
end
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleDelArea(a_Split, a_Player)
|
||||
-- Command syntax: ProtDelArea AreaID
|
||||
if (#a_Split ~= 2) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedAreaID);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Parse the AreaID
|
||||
local AreaID = tonumber(a_Split[2]);
|
||||
if (AreaID == nil) then
|
||||
a_Player:SendMessage(g_Msgs.ErrParseAreaID);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Delete the area
|
||||
g_Storage:DelArea(a_Player:GetWorld():GetName(), AreaID);
|
||||
|
||||
a_Player:SendMessage(string.format(g_Msgs.AreaDeleted, AreaID));
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleGiveWand(a_Split, a_Player)
|
||||
local NumGiven = a_Player:GetInventory():AddItem(cConfig:GetWandItem());
|
||||
if (NumGiven == 1) then
|
||||
a_Player:SendMessage(g_Msgs.WandGiven);
|
||||
else
|
||||
a_Player:SendMessage(g_Msgs.ErrNoSpaceForWand);
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleListAreas(a_Split, a_Player)
|
||||
-- Command syntax: ProtListAreas [x, z]
|
||||
|
||||
local x, z;
|
||||
if (#a_Split == 1) then
|
||||
-- Get the last "wanded" coord
|
||||
local CmdState = GetCommandStateForPlayer(a_Player);
|
||||
if (CmdState == nil) then
|
||||
a_Player:SendMessage(g_Msgs.ErrCmdStateNilListAreas);
|
||||
return true;
|
||||
end
|
||||
x, z = CmdState:GetLastCoords();
|
||||
if ((x == nil) or (z == nil)) then
|
||||
a_Player:SendMessage(g_Msgs.ErrListNotWanded);
|
||||
return true;
|
||||
end
|
||||
elseif (#a_Split == 3) then
|
||||
-- Parse the coords from the command params
|
||||
x = tonumber(a_Split[2]);
|
||||
z = tonumber(a_Split[3]);
|
||||
if ((x == nil) or (z == nil)) then
|
||||
a_Player:SendMessage(g_Msgs.ErrParseCoordsListAreas);
|
||||
return true;
|
||||
end
|
||||
else
|
||||
-- Wrong number of params, report back to the user
|
||||
a_Player:SendMessage(g_Msgs.ErrSyntaxErrorListAreas);
|
||||
return true;
|
||||
end
|
||||
|
||||
a_Player:SendMessage(string.format(g_Msgs.ListAreasHeader, x, z));
|
||||
|
||||
-- List areas intersecting the coords
|
||||
local PlayerName = a_Player:GetName();
|
||||
local WorldName = a_Player:GetWorld():GetName();
|
||||
g_Storage:ForEachArea(x, z, WorldName,
|
||||
function(AreaID, MinX, MinZ, MaxX, MaxZ, CreatorName)
|
||||
local Coords = string.format("%s: {%d, %d} - {%d, %d} ", AreaID, MinX, MinZ, MaxX, MaxZ);
|
||||
local Allowance;
|
||||
if (g_Storage:IsAreaAllowed(AreaID, PlayerName, WorldName)) then
|
||||
Allowance = g_Msgs.AreaAllowed;
|
||||
else
|
||||
Allowance = g_Msgs.AreaNotAllowed;
|
||||
end
|
||||
a_Player:SendMessage(string.format(g_Msgs.ListAreasRow, Coords, Allowance, CreatorName));
|
||||
end
|
||||
);
|
||||
|
||||
a_Player:SendMessage(g_Msgs.ListAreasFooter);
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Lists all allowed users for a particular area
|
||||
function HandleListUsers(a_Split, a_Player)
|
||||
-- Command syntax: ProtListUsers AreaID
|
||||
if (#a_Split ~= 2) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedAreaID);
|
||||
end
|
||||
|
||||
-- Get the general info about the area
|
||||
local AreaID = a_Split[2];
|
||||
local WorldName = a_Player:GetWorld():GetName();
|
||||
local MinX, MinZ, MaxX, MaxZ, CreatorName = g_Storage:GetArea(AreaID, WorldName);
|
||||
if (MinX == nil) then
|
||||
a_Player:SendMessage(string.format(g_Msgs.ErrNoSuchArea, AreaID));
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Send the header
|
||||
a_Player:SendMessage(string.format(g_Msgs.ListUsersHeader, AreaID, MinX, MinZ, MaxX, MaxZ, CreatorName));
|
||||
|
||||
-- List and count the allowed users
|
||||
local NumUsers = 0;
|
||||
g_Storage:ForEachUserInArea(AreaID, WorldName,
|
||||
function(UserName)
|
||||
a_Player:SendMessage(string.format(g_Msgs.ListUsersRow, UserName));
|
||||
NumUsers = NumUsers + 1;
|
||||
end
|
||||
);
|
||||
|
||||
-- Send the footer
|
||||
a_Player:SendMessage(string.format(g_Msgs.ListUsersFooter, AreaID, NumUsers));
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleRemoveUser(a_Split, a_Player)
|
||||
-- Command syntax: ProtRemUser AreaID UserName
|
||||
if (#a_Split ~= 3) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedAreaIDUserName);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Parse the AreaID
|
||||
local AreaID = tonumber(a_Split[2]);
|
||||
if (AreaID == nil) then
|
||||
a_Player:SendMessage(g_Msgs.ErrParseAreaID);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Remove the user from the DB
|
||||
local UserName = a_Split[3];
|
||||
g_Storage:RemoveUser(AreaID, UserName, a_Player:GetWorld():GetName());
|
||||
|
||||
-- Send confirmation
|
||||
a_Player:SendMessage(string.format(g_Msgs.RemovedUser, UserName, AreaID));
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleRemoveUserAll(a_Split, a_Player)
|
||||
-- Command syntax: ProtRemUserAll UserName
|
||||
if (#a_Split ~= 2) then
|
||||
a_Player:SendMessage(g_Msgs.ErrExpectedUserName);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Remove the user from the DB
|
||||
g_Storage:RemoveUserAll(a_Split[2], a_Player:GetWorld():GetName());
|
||||
|
||||
-- Send confirmation
|
||||
a_Player:SendMessage(string.format(g_Msgs.RemovedUserAll, UserName));
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,121 +1,121 @@
|
||||
|
||||
-- CommandState.lua
|
||||
|
||||
-- Implements the cCommandState class representing a command state for each VIP player
|
||||
|
||||
--[[
|
||||
The command state holds internal info, such as the coords they selected using the wand
|
||||
The command state needs to be held in a per-entity manner, so that we can support multiple logins
|
||||
from the same account (just for the fun of it)
|
||||
The OOP class implementation follows the PiL 16.1
|
||||
|
||||
Also, a global table g_CommandStates is the map of PlayerEntityID -> cCommandState
|
||||
--]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cCommandState = {
|
||||
-- Default coords
|
||||
m_Coords1 = {x = 0, z = 0}; -- lclk coords
|
||||
m_Coords2 = {x = 0, z = 0}; -- rclk coords
|
||||
m_LastCoords = 0; -- When Coords1 or Coords2 is set, this gets set to 1 or 2, signifying the last changed set of coords
|
||||
m_HasCoords1 = false; -- Set to true when m_Coords1 has been set by the user
|
||||
m_HasCoords2 = false; -- Set to true when m_Coords2 has been set by the user
|
||||
};
|
||||
|
||||
g_CommandStates = {};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function cCommandState:new(obj)
|
||||
obj = obj or {};
|
||||
setmetatable(obj, self);
|
||||
self.__index = self;
|
||||
return obj;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns the current coord pair as a cCuboid object
|
||||
function cCommandState:GetCurrentCuboid()
|
||||
if (not(self.m_HasCoords1) or not(self.m_HasCoords2)) then
|
||||
-- Some of the coords haven't been set yet
|
||||
return nil;
|
||||
end
|
||||
|
||||
local res = cCuboid(
|
||||
self.m_Coords1.x, 0, self.m_Coords1.z,
|
||||
self.m_Coords2.x, 255, self.m_Coords2.z
|
||||
);
|
||||
res:Sort();
|
||||
return res;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns the x, z coords that were the set last,
|
||||
-- That is, either m_Coords1 or m_Coords2, based on m_LastCoords member
|
||||
-- Returns nothing if no coords were set yet
|
||||
function cCommandState:GetLastCoords()
|
||||
if (self.m_LastCoords == 0) then
|
||||
-- No coords have been set yet
|
||||
return;
|
||||
elseif (self.m_LastCoords == 1) then
|
||||
return self.m_Coords1.x, self.m_Coords1.z;
|
||||
elseif (self.m_LastCoords == 2) then
|
||||
return self.m_Coords2.x, self.m_Coords2.z;
|
||||
else
|
||||
LOGWARNING(PluginPrefix .. "cCommandState is in an unexpected state, m_LastCoords == " .. self.m_LastCoords);
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Sets the first set of coords (upon rclk with a wand)
|
||||
function cCommandState:SetCoords1(a_BlockX, a_BlockZ)
|
||||
self.m_Coords1.x = a_BlockX;
|
||||
self.m_Coords1.z = a_BlockZ;
|
||||
self.m_LastCoords = 1;
|
||||
self.m_HasCoords1 = true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Sets the second set of coords (upon lclk with a wand)
|
||||
function cCommandState:SetCoords2(a_BlockX, a_BlockZ)
|
||||
self.m_Coords2.x = a_BlockX;
|
||||
self.m_Coords2.z = a_BlockZ;
|
||||
self.m_LastCoords = 2;
|
||||
self.m_HasCoords2 = true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns the cCommandState for the specified player; creates one if not existant
|
||||
function GetCommandStateForPlayer(a_Player)
|
||||
local res = g_CommandStates[a_Player:GetUniqueID()];
|
||||
if (res == nil) then
|
||||
res = cCommandState:new();
|
||||
g_CommandStates[a_Player:GetUniqueID()] = res;
|
||||
end
|
||||
return res;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- CommandState.lua
|
||||
|
||||
-- Implements the cCommandState class representing a command state for each VIP player
|
||||
|
||||
--[[
|
||||
The command state holds internal info, such as the coords they selected using the wand
|
||||
The command state needs to be held in a per-entity manner, so that we can support multiple logins
|
||||
from the same account (just for the fun of it)
|
||||
The OOP class implementation follows the PiL 16.1
|
||||
|
||||
Also, a global table g_CommandStates is the map of PlayerEntityID -> cCommandState
|
||||
--]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cCommandState = {
|
||||
-- Default coords
|
||||
m_Coords1 = {x = 0, z = 0}; -- lclk coords
|
||||
m_Coords2 = {x = 0, z = 0}; -- rclk coords
|
||||
m_LastCoords = 0; -- When Coords1 or Coords2 is set, this gets set to 1 or 2, signifying the last changed set of coords
|
||||
m_HasCoords1 = false; -- Set to true when m_Coords1 has been set by the user
|
||||
m_HasCoords2 = false; -- Set to true when m_Coords2 has been set by the user
|
||||
};
|
||||
|
||||
g_CommandStates = {};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function cCommandState:new(obj)
|
||||
obj = obj or {};
|
||||
setmetatable(obj, self);
|
||||
self.__index = self;
|
||||
return obj;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns the current coord pair as a cCuboid object
|
||||
function cCommandState:GetCurrentCuboid()
|
||||
if (not(self.m_HasCoords1) or not(self.m_HasCoords2)) then
|
||||
-- Some of the coords haven't been set yet
|
||||
return nil;
|
||||
end
|
||||
|
||||
local res = cCuboid(
|
||||
self.m_Coords1.x, 0, self.m_Coords1.z,
|
||||
self.m_Coords2.x, 255, self.m_Coords2.z
|
||||
);
|
||||
res:Sort();
|
||||
return res;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns the x, z coords that were the set last,
|
||||
-- That is, either m_Coords1 or m_Coords2, based on m_LastCoords member
|
||||
-- Returns nothing if no coords were set yet
|
||||
function cCommandState:GetLastCoords()
|
||||
if (self.m_LastCoords == 0) then
|
||||
-- No coords have been set yet
|
||||
return;
|
||||
elseif (self.m_LastCoords == 1) then
|
||||
return self.m_Coords1.x, self.m_Coords1.z;
|
||||
elseif (self.m_LastCoords == 2) then
|
||||
return self.m_Coords2.x, self.m_Coords2.z;
|
||||
else
|
||||
LOGWARNING(PluginPrefix .. "cCommandState is in an unexpected state, m_LastCoords == " .. self.m_LastCoords);
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Sets the first set of coords (upon rclk with a wand)
|
||||
function cCommandState:SetCoords1(a_BlockX, a_BlockZ)
|
||||
self.m_Coords1.x = a_BlockX;
|
||||
self.m_Coords1.z = a_BlockZ;
|
||||
self.m_LastCoords = 1;
|
||||
self.m_HasCoords1 = true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Sets the second set of coords (upon lclk with a wand)
|
||||
function cCommandState:SetCoords2(a_BlockX, a_BlockZ)
|
||||
self.m_Coords2.x = a_BlockX;
|
||||
self.m_Coords2.z = a_BlockZ;
|
||||
self.m_LastCoords = 2;
|
||||
self.m_HasCoords2 = true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns the cCommandState for the specified player; creates one if not existant
|
||||
function GetCommandStateForPlayer(a_Player)
|
||||
local res = g_CommandStates[a_Player:GetUniqueID()];
|
||||
if (res == nil) then
|
||||
res = cCommandState:new();
|
||||
g_CommandStates[a_Player:GetUniqueID()] = res;
|
||||
end
|
||||
return res;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,55 +1,55 @@
|
||||
|
||||
-- Config.lua
|
||||
|
||||
-- Implements the cConfig class that holds the general plugin configuration
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cConfig = {
|
||||
m_Wand = cItem(E_ITEM_STICK, 1, 1); -- The item to be used as the selection wand
|
||||
m_AllowInteractNoArea = true; -- If there's no area, is a player allowed to build / dig?
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Initializes the cConfig object, loads the configuration from an INI file
|
||||
function InitializeConfig()
|
||||
local ini = cIniFile("ProtectionAreas.ini");
|
||||
if (not(ini:ReadFile())) then
|
||||
LOGINFO(PluginPrefix .. "Cannot read ProtectionAreas.ini, all plugin configuration is set to defaults");
|
||||
end
|
||||
local WandItem = cItem();
|
||||
if (
|
||||
StringToItem(ini:GetValueSet("ProtectionAreas", "WandItem", ItemToString(cConfig.m_Wand)), WandItem) and
|
||||
IsValidItem(WandItem.m_ItemType)
|
||||
) then
|
||||
cConfig.m_Wand = WandItem;
|
||||
end
|
||||
cConfig.m_AllowInteractNoArea = ini:GetValueSetB("ProtectionAreas", "AllowInteractNoArea", cConfig.m_AllowInteractNoArea);
|
||||
ini:WriteFile();
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns true if a_Item is the wand tool item
|
||||
function cConfig:IsWand(a_Item)
|
||||
return (
|
||||
(a_Item.m_ItemType == self.m_Wand.m_ItemType) and
|
||||
(a_Item.m_ItemDamage == self.m_Wand.m_ItemDamage)
|
||||
);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns the wand tool item as a cItem object
|
||||
function cConfig:GetWandItem()
|
||||
return self.m_Wand;
|
||||
|
||||
-- Config.lua
|
||||
|
||||
-- Implements the cConfig class that holds the general plugin configuration
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cConfig = {
|
||||
m_Wand = cItem(E_ITEM_STICK, 1, 1); -- The item to be used as the selection wand
|
||||
m_AllowInteractNoArea = true; -- If there's no area, is a player allowed to build / dig?
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Initializes the cConfig object, loads the configuration from an INI file
|
||||
function InitializeConfig()
|
||||
local ini = cIniFile("ProtectionAreas.ini");
|
||||
if (not(ini:ReadFile())) then
|
||||
LOGINFO(PluginPrefix .. "Cannot read ProtectionAreas.ini, all plugin configuration is set to defaults");
|
||||
end
|
||||
local WandItem = cItem();
|
||||
if (
|
||||
StringToItem(ini:GetValueSet("ProtectionAreas", "WandItem", ItemToString(cConfig.m_Wand)), WandItem) and
|
||||
IsValidItem(WandItem.m_ItemType)
|
||||
) then
|
||||
cConfig.m_Wand = WandItem;
|
||||
end
|
||||
cConfig.m_AllowInteractNoArea = ini:GetValueSetB("ProtectionAreas", "AllowInteractNoArea", cConfig.m_AllowInteractNoArea);
|
||||
ini:WriteFile();
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns true if a_Item is the wand tool item
|
||||
function cConfig:IsWand(a_Item)
|
||||
return (
|
||||
(a_Item.m_ItemType == self.m_Wand.m_ItemType) and
|
||||
(a_Item.m_ItemDamage == self.m_Wand.m_ItemDamage)
|
||||
);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns the wand tool item as a cItem object
|
||||
function cConfig:GetWandItem()
|
||||
return self.m_Wand;
|
||||
end
|
@ -1,76 +1,76 @@
|
||||
|
||||
-- CurrentLng.lua
|
||||
-- This file provides all the translatable strings
|
||||
-- The expectation is that the translators will create copies of this file, translate the texts and then the users will overwrite this file with a specific language version
|
||||
-- Note that the individual languages must not have ".lua" extension, otherwise MCServer will load them and the plugin won't work!
|
||||
|
||||
|
||||
|
||||
|
||||
-- Individual commands, and their help strings. Don't touch the first symbol on each line!
|
||||
-- This needs to be implemented as a function, because it references other functions which might not yet be loaded while Lua is processing the globals
|
||||
|
||||
function CommandReg()
|
||||
return {
|
||||
-- Handler function | Command | Permission | Help text
|
||||
{HandleAddArea, "/ProtAdd", "Prot.Add", "<UserNames> - Adds a new protected area"},
|
||||
{HandleAddAreaCoords, "/ProtAddCoords", "Prot.Add", "<x1> <z1> <x2> <z2> <UserNames> - Adds a new protected area by coords"},
|
||||
{HandleAddAreaUser, "/ProtAddUser", "Prot.AddUser", "<AreaID> <UserNames> - Adds new users to an existing protected area"},
|
||||
{HandleDelArea, "/ProtDelID", "Prot.Del", "<AreaID> - Deletes a protected area by ID"},
|
||||
{HandleGiveWand, "/ProtWand", "Prot.Wand", " - Gives you the wand used for protection"},
|
||||
{HandleListAreas, "/ProtList", "Prot.List", "[<x> <z>] - Lists all areas for the marked block or given coords"},
|
||||
{HandleListUsers, "/ProtUsers", "Prot.List", "<AreaID> - Lists all allowed users for a given area ID"},
|
||||
{HandleRemoveUser, "/ProtRemUser", "Prot.RemUser", "<AreaID> <UserName> - Removes a user from the protected area"},
|
||||
{HandleRemoveUserAll, "/ProtRemUserAll", "Prot.RemUser", "<UserName> - Removes a user from all protected areas"},
|
||||
};
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Messages sent to players
|
||||
g_Msgs =
|
||||
{
|
||||
AllUsersAlreadyAllowed = "All the specified users were already allowed.";
|
||||
AreaAdded = "Area added, ID %s";
|
||||
AreaAllowed = "Allowed";
|
||||
AreaDeleted = "Area ID %s deleted";
|
||||
AreaNotAllowed = "NOT allowed";
|
||||
Coords1Set = "Coords1 set as {%d, %d}";
|
||||
Coords2Set = "Coords2 set as {%d, %d}";
|
||||
ErrCmdStateNilAddArea = "Cannot add area, internal plugin error (CmdState == nil)";
|
||||
ErrCmdStateNilListAreas = "Cannot list areas, internal plugin error (CmdState == nil)";
|
||||
ErrDBFailAddUsers = "Cannot add users, DB failure";
|
||||
ErrExpectedAreaID = "Parameter mismatch. Expected <AreaID>.";
|
||||
ErrExpectedAreaIDUserName = "Parameter mismatch. Expected <AreaID> <UserName>.";
|
||||
ErrExpectedAreaIDUsernames = "Not enough parameters. Expected <AreaID> and a list of usernames.";
|
||||
ErrExpectedCoordsUsernames = "Not enough parameters. Expected <x1> <z1> <x2> <z2> coords and a list of usernames.";
|
||||
ErrExpectedListOfUsernames = "Not enough parameters. Expected a list of usernames.";
|
||||
ErrExpectedUserName = "Parameter mismatch. Expected <UserName>.";
|
||||
ErrListNotWanded = "Cannot list areas, no query point has been selected. Use a ProtWand lclk / rclk to select a point first";
|
||||
ErrNoAreaWanded = "Cannot add area, no area has been selected. Use a ProtWand lclk / rclk to select area first";
|
||||
ErrNoSpaceForWand = "Cannot give wand, no space in your inventory";
|
||||
ErrNoSuchArea = "No such area: %s";
|
||||
ErrParseAreaID = "Cannot parse <AreaID>.";
|
||||
ErrParseCoords = "Cannot parse coords.";
|
||||
ErrParseCoordsListAreas = "Cannot list areas, cannot parse coords in params";
|
||||
ErrSyntaxErrorListAreas = "Cannot list areas, syntax error. Expected either no params or <x> <z>.";
|
||||
ListAreasFooter = "Area list finished";
|
||||
ListAreasHeader = "Listing protection areas intersecting block column {%d, %d}:";
|
||||
ListAreasRow = " %s, %s, created by %s";
|
||||
ListUsersFooter = "End of area %s user list, total %d users";
|
||||
ListUsersHeader = "Area ID %s: {%d, %d} - {%d, %d}, created by %s; allowed users:";
|
||||
ListUsersRow = " %s";
|
||||
NotAllowedToBuild = "You are not allowed to build here!";
|
||||
NotAllowedToDig = "You are not allowed to dig here!";
|
||||
RemovedUser = "Removed %s from area %d";
|
||||
RemovedUserAll = "Removed %s from all areas";
|
||||
UsersAdded = "Users added: %s";
|
||||
WandGiven = "Wand given";
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- CurrentLng.lua
|
||||
-- This file provides all the translatable strings
|
||||
-- The expectation is that the translators will create copies of this file, translate the texts and then the users will overwrite this file with a specific language version
|
||||
-- Note that the individual languages must not have ".lua" extension, otherwise MCServer will load them and the plugin won't work!
|
||||
|
||||
|
||||
|
||||
|
||||
-- Individual commands, and their help strings. Don't touch the first symbol on each line!
|
||||
-- This needs to be implemented as a function, because it references other functions which might not yet be loaded while Lua is processing the globals
|
||||
|
||||
function CommandReg()
|
||||
return {
|
||||
-- Handler function | Command | Permission | Help text
|
||||
{HandleAddArea, "/ProtAdd", "Prot.Add", "<UserNames> - Adds a new protected area"},
|
||||
{HandleAddAreaCoords, "/ProtAddCoords", "Prot.Add", "<x1> <z1> <x2> <z2> <UserNames> - Adds a new protected area by coords"},
|
||||
{HandleAddAreaUser, "/ProtAddUser", "Prot.AddUser", "<AreaID> <UserNames> - Adds new users to an existing protected area"},
|
||||
{HandleDelArea, "/ProtDelID", "Prot.Del", "<AreaID> - Deletes a protected area by ID"},
|
||||
{HandleGiveWand, "/ProtWand", "Prot.Wand", " - Gives you the wand used for protection"},
|
||||
{HandleListAreas, "/ProtList", "Prot.List", "[<x> <z>] - Lists all areas for the marked block or given coords"},
|
||||
{HandleListUsers, "/ProtUsers", "Prot.List", "<AreaID> - Lists all allowed users for a given area ID"},
|
||||
{HandleRemoveUser, "/ProtRemUser", "Prot.RemUser", "<AreaID> <UserName> - Removes a user from the protected area"},
|
||||
{HandleRemoveUserAll, "/ProtRemUserAll", "Prot.RemUser", "<UserName> - Removes a user from all protected areas"},
|
||||
};
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Messages sent to players
|
||||
g_Msgs =
|
||||
{
|
||||
AllUsersAlreadyAllowed = "All the specified users were already allowed.";
|
||||
AreaAdded = "Area added, ID %s";
|
||||
AreaAllowed = "Allowed";
|
||||
AreaDeleted = "Area ID %s deleted";
|
||||
AreaNotAllowed = "NOT allowed";
|
||||
Coords1Set = "Coords1 set as {%d, %d}";
|
||||
Coords2Set = "Coords2 set as {%d, %d}";
|
||||
ErrCmdStateNilAddArea = "Cannot add area, internal plugin error (CmdState == nil)";
|
||||
ErrCmdStateNilListAreas = "Cannot list areas, internal plugin error (CmdState == nil)";
|
||||
ErrDBFailAddUsers = "Cannot add users, DB failure";
|
||||
ErrExpectedAreaID = "Parameter mismatch. Expected <AreaID>.";
|
||||
ErrExpectedAreaIDUserName = "Parameter mismatch. Expected <AreaID> <UserName>.";
|
||||
ErrExpectedAreaIDUsernames = "Not enough parameters. Expected <AreaID> and a list of usernames.";
|
||||
ErrExpectedCoordsUsernames = "Not enough parameters. Expected <x1> <z1> <x2> <z2> coords and a list of usernames.";
|
||||
ErrExpectedListOfUsernames = "Not enough parameters. Expected a list of usernames.";
|
||||
ErrExpectedUserName = "Parameter mismatch. Expected <UserName>.";
|
||||
ErrListNotWanded = "Cannot list areas, no query point has been selected. Use a ProtWand lclk / rclk to select a point first";
|
||||
ErrNoAreaWanded = "Cannot add area, no area has been selected. Use a ProtWand lclk / rclk to select area first";
|
||||
ErrNoSpaceForWand = "Cannot give wand, no space in your inventory";
|
||||
ErrNoSuchArea = "No such area: %s";
|
||||
ErrParseAreaID = "Cannot parse <AreaID>.";
|
||||
ErrParseCoords = "Cannot parse coords.";
|
||||
ErrParseCoordsListAreas = "Cannot list areas, cannot parse coords in params";
|
||||
ErrSyntaxErrorListAreas = "Cannot list areas, syntax error. Expected either no params or <x> <z>.";
|
||||
ListAreasFooter = "Area list finished";
|
||||
ListAreasHeader = "Listing protection areas intersecting block column {%d, %d}:";
|
||||
ListAreasRow = " %s, %s, created by %s";
|
||||
ListUsersFooter = "End of area %s user list, total %d users";
|
||||
ListUsersHeader = "Area ID %s: {%d, %d} - {%d, %d}, created by %s; allowed users:";
|
||||
ListUsersRow = " %s";
|
||||
NotAllowedToBuild = "You are not allowed to build here!";
|
||||
NotAllowedToDig = "You are not allowed to dig here!";
|
||||
RemovedUser = "Removed %s from area %d";
|
||||
RemovedUserAll = "Removed %s from all areas";
|
||||
UsersAdded = "Users added: %s";
|
||||
WandGiven = "Wand given";
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,139 +1,139 @@
|
||||
|
||||
-- HookHandlers.lua
|
||||
-- Implements the handlers for individual hooks
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Registers all the hooks that the plugin needs to know about
|
||||
function InitializeHooks(a_Plugin)
|
||||
local PlgMgr = cRoot:Get():GetPluginManager();
|
||||
PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_DISCONNECT);
|
||||
PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_LEFT_CLICK);
|
||||
PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_MOVING);
|
||||
PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_RIGHT_CLICK);
|
||||
PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_SPAWNED);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS when a player's connectino is lost - either they disconnected or timed out
|
||||
function OnDisconnect(a_Player, a_Reason)
|
||||
-- Remove the player's cProtectionArea object
|
||||
g_PlayerAreas[a_Player:GetUniqueID()] = nil;
|
||||
|
||||
-- If the player is a VIP, they had a command state, remove that as well
|
||||
g_CommandStates[a_Player:GetUniqueID()] = nil;
|
||||
|
||||
return false;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS whenever a player enters a world (is spawned)
|
||||
function OnPlayerSpawned(a_Player)
|
||||
-- Create a new cPlayerAreas object for this player
|
||||
if (g_PlayerAreas[a_Player:GetUniqueID()] == nil) then
|
||||
LoadPlayerAreas(a_Player);
|
||||
end;
|
||||
|
||||
return false;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS whenever a player is moving (at most once every tick)
|
||||
function OnPlayerMoving(a_Player)
|
||||
local PlayerID = a_Player:GetUniqueID();
|
||||
|
||||
-- If for some reason we don't have a cPlayerAreas object for this player, load it up
|
||||
local PlayerAreas = g_PlayerAreas[PlayerID];
|
||||
if (PlayerAreas == nil) then
|
||||
LoadPlayerAreas(a_Player);
|
||||
return false;
|
||||
end;
|
||||
|
||||
-- If the player is outside their areas' safe space, reload
|
||||
if (not(PlayerAreas:IsInSafe(a_Player:GetPosX(), a_Player:GetPosZ()))) then
|
||||
LoadPlayerAreas(a_Player);
|
||||
end
|
||||
return false;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS when a player left-clicks
|
||||
function OnPlayerLeftClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status)
|
||||
-- If the player has lclked with the wand; regardless of their permissions, let's set the coords:
|
||||
if (cConfig:IsWand(a_Player:GetEquippedItem())) then
|
||||
-- BlockFace < 0 means "use item", for which the coords are not given by the client
|
||||
if (a_BlockFace < 0) then
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Convert the clicked coords into the block space
|
||||
a_BlockX, a_BlockY, a_BlockZ = AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
||||
|
||||
-- Set the coords in the CommandState
|
||||
GetCommandStateForPlayer(a_Player):SetCoords1(a_BlockX, a_BlockZ);
|
||||
a_Player:SendMessage(string.format(g_Msgs.Coords1Set, a_BlockX, a_BlockZ));
|
||||
return true;
|
||||
end;
|
||||
|
||||
-- Check the player areas to see whether to disable this action
|
||||
local Areas = g_PlayerAreas[a_Player:GetUniqueID()];
|
||||
if not(Areas:CanInteractWithBlock(a_BlockX, a_BlockZ)) then
|
||||
a_Player:SendMessage(g_Msgs.NotAllowedToDig);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Allow interaction
|
||||
return false;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS when a player right-clicks
|
||||
function OnPlayerRightClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_Status)
|
||||
|
||||
-- BlockFace < 0 means "use item", for which the coords are not given by the client
|
||||
if (a_BlockFace < 0) then
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Convert the clicked coords into the block space
|
||||
a_BlockX, a_BlockY, a_BlockZ = AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
||||
|
||||
-- If the player has rclked with the wand; regardless of their permissions, let's set the coords
|
||||
if (cConfig:IsWand(a_Player:GetEquippedItem())) then
|
||||
-- Set the coords in the CommandState
|
||||
GetCommandStateForPlayer(a_Player):SetCoords2(a_BlockX, a_BlockZ);
|
||||
a_Player:SendMessage(string.format(g_Msgs.Coords2Set, a_BlockX, a_BlockZ));
|
||||
return true;
|
||||
end;
|
||||
|
||||
-- Check the player areas to see whether to disable this action
|
||||
local Areas = g_PlayerAreas[a_Player:GetUniqueID()];
|
||||
if not(Areas:CanInteractWithBlock(a_BlockX, a_BlockZ)) then
|
||||
a_Player:SendMessage(g_Msgs.NotAllowedToBuild);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Allow interaction
|
||||
return false;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- HookHandlers.lua
|
||||
-- Implements the handlers for individual hooks
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Registers all the hooks that the plugin needs to know about
|
||||
function InitializeHooks(a_Plugin)
|
||||
local PlgMgr = cRoot:Get():GetPluginManager();
|
||||
PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_DISCONNECT);
|
||||
PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_LEFT_CLICK);
|
||||
PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_MOVING);
|
||||
PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_RIGHT_CLICK);
|
||||
PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_SPAWNED);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS when a player's connectino is lost - either they disconnected or timed out
|
||||
function OnDisconnect(a_Player, a_Reason)
|
||||
-- Remove the player's cProtectionArea object
|
||||
g_PlayerAreas[a_Player:GetUniqueID()] = nil;
|
||||
|
||||
-- If the player is a VIP, they had a command state, remove that as well
|
||||
g_CommandStates[a_Player:GetUniqueID()] = nil;
|
||||
|
||||
return false;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS whenever a player enters a world (is spawned)
|
||||
function OnPlayerSpawned(a_Player)
|
||||
-- Create a new cPlayerAreas object for this player
|
||||
if (g_PlayerAreas[a_Player:GetUniqueID()] == nil) then
|
||||
LoadPlayerAreas(a_Player);
|
||||
end;
|
||||
|
||||
return false;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS whenever a player is moving (at most once every tick)
|
||||
function OnPlayerMoving(a_Player)
|
||||
local PlayerID = a_Player:GetUniqueID();
|
||||
|
||||
-- If for some reason we don't have a cPlayerAreas object for this player, load it up
|
||||
local PlayerAreas = g_PlayerAreas[PlayerID];
|
||||
if (PlayerAreas == nil) then
|
||||
LoadPlayerAreas(a_Player);
|
||||
return false;
|
||||
end;
|
||||
|
||||
-- If the player is outside their areas' safe space, reload
|
||||
if (not(PlayerAreas:IsInSafe(a_Player:GetPosX(), a_Player:GetPosZ()))) then
|
||||
LoadPlayerAreas(a_Player);
|
||||
end
|
||||
return false;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS when a player left-clicks
|
||||
function OnPlayerLeftClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status)
|
||||
-- If the player has lclked with the wand; regardless of their permissions, let's set the coords:
|
||||
if (cConfig:IsWand(a_Player:GetEquippedItem())) then
|
||||
-- BlockFace < 0 means "use item", for which the coords are not given by the client
|
||||
if (a_BlockFace < 0) then
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Convert the clicked coords into the block space
|
||||
a_BlockX, a_BlockY, a_BlockZ = AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
||||
|
||||
-- Set the coords in the CommandState
|
||||
GetCommandStateForPlayer(a_Player):SetCoords1(a_BlockX, a_BlockZ);
|
||||
a_Player:SendMessage(string.format(g_Msgs.Coords1Set, a_BlockX, a_BlockZ));
|
||||
return true;
|
||||
end;
|
||||
|
||||
-- Check the player areas to see whether to disable this action
|
||||
local Areas = g_PlayerAreas[a_Player:GetUniqueID()];
|
||||
if not(Areas:CanInteractWithBlock(a_BlockX, a_BlockZ)) then
|
||||
a_Player:SendMessage(g_Msgs.NotAllowedToDig);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Allow interaction
|
||||
return false;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS when a player right-clicks
|
||||
function OnPlayerRightClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_Status)
|
||||
|
||||
-- BlockFace < 0 means "use item", for which the coords are not given by the client
|
||||
if (a_BlockFace < 0) then
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Convert the clicked coords into the block space
|
||||
a_BlockX, a_BlockY, a_BlockZ = AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
||||
|
||||
-- If the player has rclked with the wand; regardless of their permissions, let's set the coords
|
||||
if (cConfig:IsWand(a_Player:GetEquippedItem())) then
|
||||
-- Set the coords in the CommandState
|
||||
GetCommandStateForPlayer(a_Player):SetCoords2(a_BlockX, a_BlockZ);
|
||||
a_Player:SendMessage(string.format(g_Msgs.Coords2Set, a_BlockX, a_BlockZ));
|
||||
return true;
|
||||
end;
|
||||
|
||||
-- Check the player areas to see whether to disable this action
|
||||
local Areas = g_PlayerAreas[a_Player:GetUniqueID()];
|
||||
if not(Areas:CanInteractWithBlock(a_BlockX, a_BlockZ)) then
|
||||
a_Player:SendMessage(g_Msgs.NotAllowedToBuild);
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Allow interaction
|
||||
return false;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
ProtectionAreas license
|
||||
=======================
|
||||
|
||||
The ProtectionAreas plugin is written by _Xoft(o) / Mattes and is hereby released as public domain.
|
||||
|
||||
If you like it, I'd really appreciate a postcard, or something tiny typical from your country :) The current snailmail address is at my personal web, http://xoft.cz .
|
||||
|
||||
ProtectionAreas license
|
||||
=======================
|
||||
|
||||
The ProtectionAreas plugin is written by _Xoft(o) / Mattes and is hereby released as public domain.
|
||||
|
||||
If you like it, I'd really appreciate a postcard, or something tiny typical from your country :) The current snailmail address is at my personal web, http://xoft.cz .
|
||||
|
@ -1,109 +1,109 @@
|
||||
|
||||
-- PlayerAreas.lua
|
||||
-- Implements the cPlayerAreas class representing the per-player area storage object
|
||||
|
||||
--[[
|
||||
Each player instance is expected to have a separate object of type cPlayerAreas.
|
||||
Each object has an array of {cuboid, IsAllowed} tables, one for each area that is "within reach"
|
||||
The code can then ask each object, whether the player can interact with a certain block or not.
|
||||
A player can interact with a block if either one of these is true:
|
||||
1, There are no areas covering the block
|
||||
2, There is at least one area covering the block with IsAllowed set to true
|
||||
The object also has a m_SafeCuboid object that specified the area within which the player may move
|
||||
without the PlayerAreas needing a re-query.
|
||||
|
||||
Also, a global table g_PlayerAreas is the actual map of PlayerID -> cPlayerAreas
|
||||
--]]
|
||||
|
||||
|
||||
|
||||
|
||||
cPlayerAreas = {};
|
||||
|
||||
g_PlayerAreas = {};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function cPlayerAreas:new(a_SafeMinX, a_SafeMinZ, a_SafeMaxX, a_SafeMaxZ)
|
||||
assert(a_SafeMinX);
|
||||
assert(a_SafeMinZ);
|
||||
assert(a_SafeMaxX);
|
||||
assert(a_SafeMaxZ);
|
||||
|
||||
local obj = {};
|
||||
setmetatable(obj, self);
|
||||
self.__index = self;
|
||||
self.m_SafeCuboid = cCuboid(a_SafeMinX, 0, a_SafeMinZ, a_SafeMaxX, 255, a_SafeMaxZ);
|
||||
return obj;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- Adds a new cuboid to the area list, where the player is either allowed or not, depending on the IsAllowed param
|
||||
function cPlayerAreas:AddArea(a_Cuboid, a_IsAllowed)
|
||||
table.insert(self, {m_Cuboid = a_Cuboid, m_IsAllowed = a_IsAllowed});
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- returns true if the player owning this object can interact with the specified block
|
||||
function cPlayerAreas:CanInteractWithBlock(a_BlockX, a_BlockZ)
|
||||
assert(self);
|
||||
|
||||
-- iterate through all the stored areas:
|
||||
local IsInsideAnyArea = false;
|
||||
for idx, Area in ipairs(self) do
|
||||
if (Area.m_Cuboid:IsInside(a_BlockX, 1, a_BlockZ)) then -- We don't care about Y coords, so use a dummy value
|
||||
if (Area.m_IsAllowed) then
|
||||
return true;
|
||||
end
|
||||
-- The coords are inside a cuboid for which the player doesn't have access, take a note of it
|
||||
IsInsideAnyArea = true;
|
||||
end
|
||||
end
|
||||
|
||||
if (IsInsideAnyArea) then
|
||||
-- The specified coords are inside at least one area, but none of them allow the player to interact
|
||||
return false;
|
||||
end
|
||||
|
||||
-- The coords are not inside any area
|
||||
return cConfig.m_AllowInteractNoArea;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Calls the specified callback for each area contained within
|
||||
-- a_Callback has a signature: function(a_Cuboid, a_IsAllowed)
|
||||
-- Returns true if all areas have been enumerated, false if the callback has aborted by returning true
|
||||
function cPlayerAreas:ForEachArea(a_Callback)
|
||||
assert(self);
|
||||
|
||||
for idx, Area in ipairs(self) do
|
||||
if (a_Callback(Area.m_Cuboid, Area.m_IsAllowed)) then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns true if the player is withing the safe cuboid (no need to re-query the areas)
|
||||
function cPlayerAreas:IsInSafe(a_BlockX, a_BlockZ)
|
||||
assert(self);
|
||||
return self.m_SafeCuboid:IsInside(a_BlockX, 0, a_BlockZ);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- PlayerAreas.lua
|
||||
-- Implements the cPlayerAreas class representing the per-player area storage object
|
||||
|
||||
--[[
|
||||
Each player instance is expected to have a separate object of type cPlayerAreas.
|
||||
Each object has an array of {cuboid, IsAllowed} tables, one for each area that is "within reach"
|
||||
The code can then ask each object, whether the player can interact with a certain block or not.
|
||||
A player can interact with a block if either one of these is true:
|
||||
1, There are no areas covering the block
|
||||
2, There is at least one area covering the block with IsAllowed set to true
|
||||
The object also has a m_SafeCuboid object that specified the area within which the player may move
|
||||
without the PlayerAreas needing a re-query.
|
||||
|
||||
Also, a global table g_PlayerAreas is the actual map of PlayerID -> cPlayerAreas
|
||||
--]]
|
||||
|
||||
|
||||
|
||||
|
||||
cPlayerAreas = {};
|
||||
|
||||
g_PlayerAreas = {};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function cPlayerAreas:new(a_SafeMinX, a_SafeMinZ, a_SafeMaxX, a_SafeMaxZ)
|
||||
assert(a_SafeMinX);
|
||||
assert(a_SafeMinZ);
|
||||
assert(a_SafeMaxX);
|
||||
assert(a_SafeMaxZ);
|
||||
|
||||
local obj = {};
|
||||
setmetatable(obj, self);
|
||||
self.__index = self;
|
||||
self.m_SafeCuboid = cCuboid(a_SafeMinX, 0, a_SafeMinZ, a_SafeMaxX, 255, a_SafeMaxZ);
|
||||
return obj;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- Adds a new cuboid to the area list, where the player is either allowed or not, depending on the IsAllowed param
|
||||
function cPlayerAreas:AddArea(a_Cuboid, a_IsAllowed)
|
||||
table.insert(self, {m_Cuboid = a_Cuboid, m_IsAllowed = a_IsAllowed});
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- returns true if the player owning this object can interact with the specified block
|
||||
function cPlayerAreas:CanInteractWithBlock(a_BlockX, a_BlockZ)
|
||||
assert(self);
|
||||
|
||||
-- iterate through all the stored areas:
|
||||
local IsInsideAnyArea = false;
|
||||
for idx, Area in ipairs(self) do
|
||||
if (Area.m_Cuboid:IsInside(a_BlockX, 1, a_BlockZ)) then -- We don't care about Y coords, so use a dummy value
|
||||
if (Area.m_IsAllowed) then
|
||||
return true;
|
||||
end
|
||||
-- The coords are inside a cuboid for which the player doesn't have access, take a note of it
|
||||
IsInsideAnyArea = true;
|
||||
end
|
||||
end
|
||||
|
||||
if (IsInsideAnyArea) then
|
||||
-- The specified coords are inside at least one area, but none of them allow the player to interact
|
||||
return false;
|
||||
end
|
||||
|
||||
-- The coords are not inside any area
|
||||
return cConfig.m_AllowInteractNoArea;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Calls the specified callback for each area contained within
|
||||
-- a_Callback has a signature: function(a_Cuboid, a_IsAllowed)
|
||||
-- Returns true if all areas have been enumerated, false if the callback has aborted by returning true
|
||||
function cPlayerAreas:ForEachArea(a_Callback)
|
||||
assert(self);
|
||||
|
||||
for idx, Area in ipairs(self) do
|
||||
if (a_Callback(Area.m_Cuboid, Area.m_IsAllowed)) then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns true if the player is withing the safe cuboid (no need to re-query the areas)
|
||||
function cPlayerAreas:IsInSafe(a_BlockX, a_BlockZ)
|
||||
assert(self);
|
||||
return self.m_SafeCuboid:IsInside(a_BlockX, 0, a_BlockZ);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,71 +1,71 @@
|
||||
|
||||
-- ProtectionAreas.lua
|
||||
-- Defines the main plugin entrypoint, as well as some utility functions
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Prefix for all messages logged to the server console
|
||||
PluginPrefix = "ProtectionAreas: ";
|
||||
|
||||
--- Bounds for the area loading. Areas less this far in any direction from the player will be loaded into cPlayerAreas
|
||||
g_AreaBounds = 48;
|
||||
|
||||
--- If a player moves this close to the PlayerAreas bounds, the PlayerAreas will be re-queried
|
||||
g_AreaSafeEdge = 12;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS when the plugin loads
|
||||
-- Returns true if initialization successful, false otherwise
|
||||
function Initialize(a_Plugin)
|
||||
a_Plugin:SetName("ProtectionAreas");
|
||||
a_Plugin:SetVersion(1);
|
||||
|
||||
InitializeConfig();
|
||||
if (not(InitializeStorage())) then
|
||||
LOGWARNING(PluginPrefix .. "failed to initialize Storage, plugin is disabled");
|
||||
return false;
|
||||
end
|
||||
InitializeHooks(a_Plugin);
|
||||
InitializeCommandHandlers();
|
||||
|
||||
-- We might be reloading, so there may be players already present in the server; reload all of them
|
||||
cRoot:Get():ForEachWorld(
|
||||
function(a_World)
|
||||
ReloadAllPlayersInWorld(a_World:GetName());
|
||||
end
|
||||
);
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Loads a cPlayerAreas object from the DB for the player, and assigns it to the player map
|
||||
function LoadPlayerAreas(a_Player)
|
||||
local PlayerID = a_Player:GetUniqueID();
|
||||
local PlayerX = math.floor(a_Player:GetPosX());
|
||||
local PlayerZ = math.floor(a_Player:GetPosZ());
|
||||
local WorldName = a_Player:GetWorld():GetName();
|
||||
g_PlayerAreas[PlayerID] = g_Storage:LoadPlayerAreas(a_Player:GetName(), PlayerX, PlayerZ, WorldName);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function ReloadAllPlayersInWorld(a_WorldName)
|
||||
local World = cRoot:Get():GetWorld(a_WorldName);
|
||||
World:ForEachPlayer(LoadPlayerAreas);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- ProtectionAreas.lua
|
||||
-- Defines the main plugin entrypoint, as well as some utility functions
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Prefix for all messages logged to the server console
|
||||
PluginPrefix = "ProtectionAreas: ";
|
||||
|
||||
--- Bounds for the area loading. Areas less this far in any direction from the player will be loaded into cPlayerAreas
|
||||
g_AreaBounds = 48;
|
||||
|
||||
--- If a player moves this close to the PlayerAreas bounds, the PlayerAreas will be re-queried
|
||||
g_AreaSafeEdge = 12;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Called by MCS when the plugin loads
|
||||
-- Returns true if initialization successful, false otherwise
|
||||
function Initialize(a_Plugin)
|
||||
a_Plugin:SetName("ProtectionAreas");
|
||||
a_Plugin:SetVersion(1);
|
||||
|
||||
InitializeConfig();
|
||||
if (not(InitializeStorage())) then
|
||||
LOGWARNING(PluginPrefix .. "failed to initialize Storage, plugin is disabled");
|
||||
return false;
|
||||
end
|
||||
InitializeHooks(a_Plugin);
|
||||
InitializeCommandHandlers();
|
||||
|
||||
-- We might be reloading, so there may be players already present in the server; reload all of them
|
||||
cRoot:Get():ForEachWorld(
|
||||
function(a_World)
|
||||
ReloadAllPlayersInWorld(a_World:GetName());
|
||||
end
|
||||
);
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Loads a cPlayerAreas object from the DB for the player, and assigns it to the player map
|
||||
function LoadPlayerAreas(a_Player)
|
||||
local PlayerID = a_Player:GetUniqueID();
|
||||
local PlayerX = math.floor(a_Player:GetPosX());
|
||||
local PlayerZ = math.floor(a_Player:GetPosZ());
|
||||
local WorldName = a_Player:GetWorld():GetName();
|
||||
g_PlayerAreas[PlayerID] = g_Storage:LoadPlayerAreas(a_Player:GetName(), PlayerX, PlayerZ, WorldName);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function ReloadAllPlayersInWorld(a_WorldName)
|
||||
local World = cRoot:Get():GetWorld(a_WorldName);
|
||||
World:ForEachPlayer(LoadPlayerAreas);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,13 @@
|
||||
class SquirrelChatLog extends Plugin
|
||||
{
|
||||
function Initialize()
|
||||
{
|
||||
this.AddHook(Hook.Chat);
|
||||
return true;
|
||||
}
|
||||
|
||||
function OnChat(Message, Player)
|
||||
{
|
||||
::print(Player.GetName() + ": " + Message);
|
||||
}
|
||||
}
|
||||
class SquirrelChatLog extends Plugin
|
||||
{
|
||||
function Initialize()
|
||||
{
|
||||
this.AddHook(Hook.Chat);
|
||||
return true;
|
||||
}
|
||||
|
||||
function OnChat(Message, Player)
|
||||
{
|
||||
::print(Player.GetName() + ": " + Message);
|
||||
}
|
||||
}
|
||||
|
@ -1,392 +1,392 @@
|
||||
|
||||
# This file describes the crafting recipes that MCServer knows.
|
||||
# The syntax is as follows:
|
||||
# <Line> = <Recipe>#<Comment>
|
||||
# <Recipe> = <Result> = <Ingredient1> | <Ingredient2> | ... | <IngredientN>
|
||||
# <IngredientN> = <ItemID>, <X1> : <Y1>, <X2> : <Y2>, ..., <Xn> : <Yn>
|
||||
# <ItemID> = <ItemType> [^<DamageValue>]
|
||||
# <Xn>, <Yn> = "1" .. "3", or "*" for any value. "*:*" can be replaced by a single "*".
|
||||
# <Result> = <ItemType> [^<DamageValue>] [, <Count>]
|
||||
#
|
||||
# The Xn, Yn coordinates are a reference to the crafting grid:
|
||||
# 1:1 | 2:1 | 3:1
|
||||
# 1:2 | 2:2 | 3:2
|
||||
# 1:3 | 2:3 | 3:3
|
||||
#
|
||||
# <ItemType> can be either a number, or an item name (checked against items.ini)
|
||||
#
|
||||
# ^<DamageValue> is optional, if not present, any damage value is matched for ingredients and zero is produced for the result
|
||||
#
|
||||
# Ingredients with an asterisk for a coord will not match already matched crafting grid items. This enables simplifying some of the recipes,
|
||||
# e. g. hoe: "Iron, 2:1, *:1"
|
||||
# -- this means "one iron at 2:1, and another one at either 1:1 or 3:1"
|
||||
#
|
||||
# To require multiple items of the same type in a slot, specify the slot number several times:
|
||||
# "Iron, 1:1, 2:2, 2:2"
|
||||
# -- this means "take one iron from slot 1:1 and two irons from slot 2:2"
|
||||
# Note that asterisked items cannot require multiple items in a single slot.
|
||||
#
|
||||
# Note that due to technical problems, it is NOT advised to use asterisked ingredients in crossing directions, such as "*:1, "2:*".
|
||||
# The parser may be unable to match such a recipe to the crafting grid!
|
||||
#
|
||||
# Whitespace is optional. Use it reasonably. Please do NOT use Tabs in the middle of lines!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Basic Crafts
|
||||
#
|
||||
|
||||
# Need to list each of the four log types, otherwise all logs would get converted into apple planks (^0)
|
||||
ApplePlanks, 4 = AppleLog, *
|
||||
ConiferPlanks, 4 = ConiferLog, *
|
||||
BirchPlanks, 4 = BirchLog, *
|
||||
JunglePlanks, 4 = JungleLog, *
|
||||
Stick, 4 = Planks, 2:2, 2:3
|
||||
Torch, 4 = Stick, 1:2 | Coal, 1:1
|
||||
Workbench = Planks, 1:1, 1:2, 2:1, 2:2
|
||||
Chest = Planks, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
|
||||
TrappedChest = TripWireHook, 1:1 | Chest, 2:1
|
||||
EnderChest = EyeOfEnder, 2:2 | Obsidian, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
|
||||
Furnace = Cobblestone, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Blocks
|
||||
#
|
||||
IronBlock = IronIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
GoldBlock = GoldIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
DiamondBlock = Diamond, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
LapisBlock = LapisLazuli, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
EmeraldBlock = Emerald, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
RedstoneBlock = RedstoneDust, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
QuartzBlock = NetherQuartz, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
NetherBrick = netherbrickitem, 1:1, 1:2, 2:1, 2:2
|
||||
Glowstone = GlowstoneDust, 1:1, 1:2, 2:1, 2:2
|
||||
Wool = String, 1:1, 1:2, 2:1, 2:2
|
||||
TNT = Gunpowder, 1:1, 3:1, 2:2, 1:3, 3:3 | Sand, 2:1, 1:2, 3:2, 2:3
|
||||
PillarQuartzBlock = QuartzSlab, 1:1, 1:2
|
||||
ChiseledQuartzBlock, 2 = QuartzBlock, 1:1, 1:2
|
||||
|
||||
# Slabs:
|
||||
StoneSlab, 6 = Stone, 1:1, 2:1, 3:1
|
||||
SandstoneSlab, 6 = Sandstone, 1:1, 2:1, 3:1
|
||||
WoodSlab, 6 = Planks, 1:1, 2:1, 3:1
|
||||
CobblestoneSlab, 6 = Cobblestone, 1:1, 2:1, 3:1
|
||||
BrickSlab, 6 = BrickBlock, 1:1, 2:1, 3:1
|
||||
StonebrickSlab, 6 = StoneBrick, 1:1, 2:1, 3:1
|
||||
NetherbrickSlab, 6 = NetherBrick, 1:1, 2:1, 3:1
|
||||
Quartzslab, 6 = QuartzBlock, 1:1, 2:1, 3:1
|
||||
snow, 6 = SnowBlock, 1:1, 2:1, 3:1
|
||||
|
||||
# Stairs:
|
||||
WoodStairs, 4 = Planks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
WoodStairs, 4 = Planks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
cobblestoneStairs, 4 = Cobblestone, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
cobblestoneStairs, 4 = Cobblestone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
BrickStairs, 4 = BrickBlock, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
BrickStairs, 4 = BrickBlock, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
SandstoneStairs, 4 = Sandstone, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
SandstoneStairs, 4 = Sandstone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
NetherBrickStairs, 4 = NetherBrick, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
quartzstairs, 4 = QuartzBlock, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
SnowBlock = SnowBall, 1:1, 1:2, 2:1, 2:2
|
||||
ClayBlock = Clay, 1:1, 1:2, 2:1, 2:2
|
||||
BrickBlock = Brick, 1:1, 1:2, 2:1, 2:2
|
||||
StoneBrick, 4 = Stone, 1:1, 1:2, 2:1, 2:2
|
||||
BookShelf = Planks, 1:1, 2:1, 3:1, 1:3, 2:3, 3:3 | Book, 1:2, 2:2, 3:2
|
||||
Sandstone, 4 = Sand, 1:1, 1:2, 2:1, 2:2
|
||||
SmoothSandstone, 4 = Sandstone, 1:1, 1:2, 2:1, 2:2
|
||||
OrnamentSandstone = SandstoneSlab, 1:1, 1:2
|
||||
JackOLantern = Pumpkin, 1:1 | Torch, 1:2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Tools
|
||||
#
|
||||
|
||||
# Axes:
|
||||
WoodenAxe = Stick, 2:2, 2:3 | Planks, 2:1, 1:1, 1:2
|
||||
WoodenAxe = Stick, 2:2, 2:3 | Planks, 2:1, 3:1, 3:2
|
||||
StoneAxe = Stick, 2:2, 2:3 | Cobblestone, 2:1, 1:1, 1:2
|
||||
StoneAxe = Stick, 2:2, 2:3 | Cobblestone, 2:1, 3:1, 3:2
|
||||
GoldenAxe = Stick, 2:2, 2:3 | GoldIngot, 2:1, 1:1, 1:2
|
||||
GoldenAxe = Stick, 2:2, 2:3 | GoldIngot, 2:1, 3:1, 3:2
|
||||
IronAxe = Stick, 2:2, 2:3 | IronIngot, 2:1, 1:1, 1:2
|
||||
IronAxe = Stick, 2:2, 2:3 | IronIngot, 2:1, 3:1, 3:2
|
||||
DiamondAxe = Stick, 2:2, 2:3 | Diamond, 2:1, 1:1, 1:2
|
||||
DiamondAxe = Stick, 2:2, 2:3 | Diamond, 2:1, 3:1, 3:2
|
||||
|
||||
# Pickaxes:
|
||||
WoodenPickaxe = Stick, 2:2, 2:3 | Planks, 1:1, 2:1, 3:1
|
||||
StonePickaxe = Stick, 2:2, 2:3 | Cobblestone, 1:1, 2:1, 3:1
|
||||
GoldenPickaxe = Stick, 2:2, 2:3 | GoldIngot, 1:1, 2:1, 3:1
|
||||
IronPickaxe = Stick, 2:2, 2:3 | IronIngot, 1:1, 2:1, 3:1
|
||||
DiamondPickaxe = Stick, 2:2, 2:3 | Diamond, 1:1, 2:1, 3:1
|
||||
|
||||
# Shovels:
|
||||
WoodenShovel = Stick, 2:2, 2:3 | Planks, 2:1
|
||||
StoneShovel = Stick, 2:2, 2:3 | Cobblestone, 2:1
|
||||
GoldenShovel = Stick, 2:2, 2:3 | GoldIngot, 2:1
|
||||
IronShovel = Stick, 2:2, 2:3 | IronIngot, 2:1
|
||||
DiamondShovel = Stick, 2:2, 2:3 | Diamond, 2:1
|
||||
|
||||
# Hoes:
|
||||
WoodenHoe = Stick, 2:2, 2:3 | Planks, 2:1, *:1
|
||||
StoneHoe = Stick, 2:2, 2:3 | Cobblestone, 2:1, *:1
|
||||
GoldenHoe = Stick, 2:2, 2:3 | GoldIngot, 2:1, *:1
|
||||
IronHoe = Stick, 2:2, 2:3 | IronIngot, 2:1, *:1
|
||||
DiamondHoe = Stick, 2:2, 2:3 | Diamond, 2:1, *:1
|
||||
|
||||
Lighter = IronIngot, 1:1 | Flint, 2:2
|
||||
Lighter = IronIngot, 2:1 | Flint, 1:2
|
||||
Bucket = IronIngot, 1:1, 2:2, 3:1
|
||||
Compass = IronIngot, 2:1, 1:2, 3:2, 2:3 | RedstoneDust, 2:2
|
||||
Map = Paper, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Compass, 2:2
|
||||
Watch = GoldIngot, 2:1, 1:2, 3:2, 2:3 | RedstoneDust, 2:2
|
||||
FishingRod = Stick, 1:3, 2:2, 3:1 | String, 3:2, 3:3
|
||||
FishingRod = Stick, 3:3, 2:2, 1:1 | String, 1:2, 1:3
|
||||
Shears = IronIngot, 1:1, 2:2
|
||||
Shears = IronIngot, 2:1, 1:2
|
||||
FireCharge = BlazePowder, * | Coal, * | Gunpowder, *
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Weapons
|
||||
#
|
||||
WoodenSword = Stick, 2:3 | Planks, 2:1, 2:2
|
||||
StoneSword = Stick, 2:3 | Cobblestone, 2:1, 2:2
|
||||
GoldenSword = Stick, 2:3 | GoldIngot, 2:1, 2:2
|
||||
IronSword = Stick, 2:3 | IronIngot, 2:1, 2:2
|
||||
DiamondSword = Stick, 2:3 | Diamond, 2:1, 2:2
|
||||
Bow = Stick, 2:1, 1:2, 2:3 | String, 3:1, 3:2, 3:3
|
||||
Bow = Stick, 2:1, 3:2, 2:3 | String, 1:1, 1:2, 1:3
|
||||
Arrow, 4 = Flint, 1:1 | Stick, 1:2 | Feather, 1:3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Armor
|
||||
#
|
||||
|
||||
# Helmets:
|
||||
LeatherHelmet = Leather, 1:1, 2:1, 3:1, 1:2, 3:2
|
||||
ChainmailHelmet = Fire, 1:1, 2:1, 3:1, 1:2, 3:2
|
||||
GoldenHelmet = GoldIngot, 1:1, 2:1, 3:1, 1:2, 3:2
|
||||
IronHelmet = IronIngot, 1:1, 2:1, 3:1, 1:2, 3:2
|
||||
DiamondHelmet = Diamond, 1:1, 2:1, 3:1, 1:2, 3:2
|
||||
|
||||
# Chestplates:
|
||||
LeatherChestplate = Leather, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
ChainmailChestplate = Fire, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
GoldenChestplate = GoldIngot, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
IronChestplate = IronIngot, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
DiamondChestplate = Diamond, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
|
||||
# Leggins:
|
||||
LeatherPants = Leather, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
|
||||
ChainmailPants = Fire, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
|
||||
GoldenPants = GoldIngot, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
|
||||
IronPants = IronIngot, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
|
||||
DiamondPants = Diamond, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
|
||||
|
||||
# Boots:
|
||||
LeatherBoots = Leather, 1:1, 3:1, 1:2, 3:2
|
||||
ChainmailBoots = Fire, 1:1, 3:1, 1:2, 3:2
|
||||
GoldenBoots = GoldIngot, 1:1, 3:1, 1:2, 3:2
|
||||
IronBoots = IronIngot, 1:1, 3:1, 1:2, 3:2
|
||||
DiamondBoots = Diamond, 1:1, 3:1, 1:2, 3:2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Transportation
|
||||
#
|
||||
CarrotOnAStick = FishingRod, 1:2 | Carrot, 2:3
|
||||
Minecart = IronIngot, 1:1, 3:1, 1:2, 2:2, 3:2
|
||||
PoweredMinecart = Minecart, * | Furnace, *
|
||||
StorageMinecart = Minecart, * | Chest, *
|
||||
TNTMinecart = Minecart, * | TNT, *
|
||||
hopperminecart = Minecart, * | Hopper, *
|
||||
Rails, 16 = IronIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 3:3 | Stick, 2:2
|
||||
PoweredRail, 6 = GoldIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 3:3 | Stick, 2:2 | RedstoneDust, 2:3
|
||||
DetectorRail, 6 = IronIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 3:3 | StonePlate, 2:2 | RedstoneDust, 2:3
|
||||
Boat = Planks, 1:1, 3:1, 1:2, 2:2, 3:2
|
||||
ActivatorRail, 6 = IronIngot, 1:1, 1:2, 1:3, 3:1, 3:2, 3:3 | Stick, 2:1, 2:3 | RedstoneTorchon, 2:2
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Mechanisms
|
||||
#
|
||||
WoodenDoor = Planks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
IronDoor = IronIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
TrapDoor, 2 = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
WoodPlate = Planks, 1:1, 2:1
|
||||
StonePlate = Stone, 1:1, 2:1
|
||||
StoneButton = Stone, 1:1
|
||||
WoodenButton = Planks, 1:1
|
||||
RedstoneTorchOn = Stick, 1:2 | RedstoneDust, 1:1
|
||||
Lever = Cobblestone, 1:2 | Stick, 1:1
|
||||
NoteBlock = Planks, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | RedstoneDust, 2:2
|
||||
Jukebox = Planks, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Diamond, 2:2
|
||||
Dispenser = Cobblestone, 1:1, 1:2, 1:3, 2:1, 3:1, 3:2, 3:3 | RedstoneDust, 2:3 | Bow, 2:2
|
||||
Dropper = Cobblestone, 1:1, 2:1, 3:1, 1:2, 1:3, 3:2, 3:3 | Hopper, 2:2 | RedstoneDust, 2:3
|
||||
Repeater = Stone, 1:2, 2:2, 3:2 | RedstoneTorchOn, 1:1, 3:1 | RedstoneDust, 2:1
|
||||
Comparator = RedstoneTorchOn, 2:1, 1:2, 3:2 | NetherQuartz, 2:2 | Stone, 1:3, 2:3, 3:3
|
||||
DaylightSensor = Glass, 1:1, 2:1, 3:1 | NetherQuartz, 1:2, 2:2, 3:2 | Woodslab, 1:3, 2:3, 3:3
|
||||
Hopper = Ironbars, 1:1, 3:1, 1:2, 3:2, 2:3 | Chest, 2:2
|
||||
Piston = Planks, 1:1, 2:1, 3:1 | RedstoneDust, 2:3 | Cobblestone, 1:2, 3:2, 1:3, 3:3 | IronIngot, 2:2
|
||||
StickyPiston = Piston, * | SlimeBall, *
|
||||
RedstoneLamp = RedstoneDust, 2:1, 1:2, 3:2, 2:3 | Glowstone, 2:2
|
||||
tripwirehook, 2 = planks, 2:3 | stick, 2:2 | ironbar, 2:1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Food
|
||||
#
|
||||
Bowl, 4 = Planks, 1:1, 2:2, 3:1
|
||||
MushroomStew = Bowl, * | BrownMushroom, * | RedMushroom, *
|
||||
Bread = Wheat, 1:1, 2:1, 3:1
|
||||
Sugar = Sugarcane, *
|
||||
Cake = MilkBucket, 1:1, 2:1, 3:1 | Sugar, 1:2, 3:2 | Egg, 2:2 | Wheat, 1:3, 2:3, 3:3
|
||||
Cookie = Wheat, *, * | CocoaBeans, *
|
||||
GoldenApple = RedApple, 2:2 | GoldNugget, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
|
||||
EnchantedGoldenApple = RedApple, 2:2 | GoldBlock, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
|
||||
Melon = MelonSlice, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
MelonSeeds = MelonSlice, *
|
||||
PumpkinSeeds, 4 = Pumpkin, *
|
||||
PumpkinPie = Pumpkin, * | Sugar, * | egg, *
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Miscellaneous
|
||||
#
|
||||
|
||||
# Minerals:
|
||||
IronIngot, 9 = IronBlock, *
|
||||
GoldIngot, 9 = GoldBlock, *
|
||||
Diamond, 9 = DiamondBlock, *
|
||||
LapisLazuli, 9 = LapisBlock, *
|
||||
Emerald, 9 = EmeraldBlock, *
|
||||
RedstoneDust, 9 = RedstoneBlock, *
|
||||
|
||||
Painting = Stick, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Wool, 2:2
|
||||
ItemFrame = Stick, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Leather, 2:2
|
||||
Sign = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2 | Stick, 2:3
|
||||
Ladder, 3 = Stick, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 3:3
|
||||
GlassPane, 16 = Glass, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
IronBars, 16 = IronIngot, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
Paper, 3 = Sugarcane, 1:1, 2:1, 3:1
|
||||
Book = Paper, *, *, * | leather, *
|
||||
Bookandquill = Book, * | feather, * | inksac, *
|
||||
Fence, 2 = Stick, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
Cobblestonewall, 6 = cobblestone, 1:2, 1:3, 2:2, 2:3, 3:2, 3:3
|
||||
mossycobblestonewall, 6 = mossycobblestone, 1:2, 1:3, 2:2, 2:3, 3:2, 3:3
|
||||
NetherBrickFence, 6 = NetherBrick, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
FenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | Planks, 2:1, 2:2
|
||||
Bed = Planks, 1:2, 2:2, 3:2 | Wool, 1:1, 2:1, 3:1
|
||||
GoldIngot = GoldNugget, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
EyeOfEnder = EnderPearl, * | BlazePowder, *
|
||||
Beacon = Glass, 1:1, 1:2, 2:1, 3:1, 3:2 | Obsidian, 1:3, 2:3, 3:3 | NetherStar, 2:2
|
||||
Anvil = IronBlock, 1:1, 2:1, 3:1 | IronIngot, 2:2, 1:3, 2:3, 3:3
|
||||
FlowerPot = Brick, 1:2, 2:3, 3:2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Dyes
|
||||
#
|
||||
|
||||
WhiteDye, 3 = Bone, *
|
||||
RedDye, 2 = Rose, *
|
||||
YellowDye, 2 = Flower, *
|
||||
|
||||
# Color mixing, duals:
|
||||
OrangeDye, 2 = YellowDye, * | RedDye, *
|
||||
CyanDye, 2 = GreenDye, * | BlueDye, *
|
||||
PurpleDye, 2 = RedDye, * | BlueDye, *
|
||||
GrayDye, 2 = BlackDye, * | WhiteDye, *
|
||||
LtBlueDye, 2 = BlueDye, * | WhiteDye, *
|
||||
PinkDye, 2 = RedDye, * | WhiteDye, *
|
||||
LimeDye, 2 = GreenDye, * | WhiteDye, *
|
||||
MagentaDye, 2 = PurpleDye, * | PinkDye, *
|
||||
LtGrayDye, 2 = GrayDye, * | WhiteDye, *
|
||||
|
||||
# triplets:
|
||||
LtGrayDye, 3 = BlackDye, * | WhiteDye, *, *
|
||||
MagentaDye, 3 = BlueDye, * | PinkDye, * | RedDye, *
|
||||
|
||||
# quads:
|
||||
MagentaDye, 4 = BlueDye, * | WhiteDye, * | RedDye, *, *
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Colored wool:
|
||||
#
|
||||
WhiteWool = Wool, * | BoneMeal, *
|
||||
OrangeWool = Wool, * | OrangeDye, *
|
||||
MagentaWool = Wool, * | MagentaDye, *
|
||||
LightBlueWool = Wool, * | LightBlueDye, *
|
||||
YellowWool = Wool, * | YellowDye, *
|
||||
LimeWool = Wool, * | LimeDye, *
|
||||
PinkWool = Wool, * | PinkDye, *
|
||||
GrayWool = Wool, * | GrayDye, *
|
||||
LightGrayWool = Wool, * | LightGrayDye, *
|
||||
CyanWool = Wool, * | CyanDye, *
|
||||
VioletWool = Wool, * | VioletDye, *
|
||||
BlueWool = Wool, * | BlueDye, *
|
||||
BrownWool = Wool, * | BrownDye, *
|
||||
GreenWool = Wool, * | GreenDye, *
|
||||
RedWool = Wool, * | RedDye, *
|
||||
BlackWool = Wool, * | BlackDye, *
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Enchantment & Brewing
|
||||
#
|
||||
GlassBottle, 3 = Glass, 1:1, 2:2, 3:1
|
||||
Cauldron = IronIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 2:3, 3:3
|
||||
BrewingStand = Cobblestone, 1:2, 2:2, 3:2 | BlazeRod, 2:1
|
||||
BlazePowder, 2 = BlazeRod, *
|
||||
MagmaCream = SlimeBall, * | BlazePowder, *
|
||||
FermentedSpiderEye = SpiderEye, * | Sugar, * | BrownMushroom, *
|
||||
GlisteringMelon = MelonSlice, * | GoldNugget, *
|
||||
GoldNugget, 9 = GoldIngot, *
|
||||
EnchantmentTable = Obsidian, 1:3, 2:3, 3:3, 2:2 | Diamond, 1:2, 3:2 | Book, 2:1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# This file describes the crafting recipes that MCServer knows.
|
||||
# The syntax is as follows:
|
||||
# <Line> = <Recipe>#<Comment>
|
||||
# <Recipe> = <Result> = <Ingredient1> | <Ingredient2> | ... | <IngredientN>
|
||||
# <IngredientN> = <ItemID>, <X1> : <Y1>, <X2> : <Y2>, ..., <Xn> : <Yn>
|
||||
# <ItemID> = <ItemType> [^<DamageValue>]
|
||||
# <Xn>, <Yn> = "1" .. "3", or "*" for any value. "*:*" can be replaced by a single "*".
|
||||
# <Result> = <ItemType> [^<DamageValue>] [, <Count>]
|
||||
#
|
||||
# The Xn, Yn coordinates are a reference to the crafting grid:
|
||||
# 1:1 | 2:1 | 3:1
|
||||
# 1:2 | 2:2 | 3:2
|
||||
# 1:3 | 2:3 | 3:3
|
||||
#
|
||||
# <ItemType> can be either a number, or an item name (checked against items.ini)
|
||||
#
|
||||
# ^<DamageValue> is optional, if not present, any damage value is matched for ingredients and zero is produced for the result
|
||||
#
|
||||
# Ingredients with an asterisk for a coord will not match already matched crafting grid items. This enables simplifying some of the recipes,
|
||||
# e. g. hoe: "Iron, 2:1, *:1"
|
||||
# -- this means "one iron at 2:1, and another one at either 1:1 or 3:1"
|
||||
#
|
||||
# To require multiple items of the same type in a slot, specify the slot number several times:
|
||||
# "Iron, 1:1, 2:2, 2:2"
|
||||
# -- this means "take one iron from slot 1:1 and two irons from slot 2:2"
|
||||
# Note that asterisked items cannot require multiple items in a single slot.
|
||||
#
|
||||
# Note that due to technical problems, it is NOT advised to use asterisked ingredients in crossing directions, such as "*:1, "2:*".
|
||||
# The parser may be unable to match such a recipe to the crafting grid!
|
||||
#
|
||||
# Whitespace is optional. Use it reasonably. Please do NOT use Tabs in the middle of lines!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Basic Crafts
|
||||
#
|
||||
|
||||
# Need to list each of the four log types, otherwise all logs would get converted into apple planks (^0)
|
||||
ApplePlanks, 4 = AppleLog, *
|
||||
ConiferPlanks, 4 = ConiferLog, *
|
||||
BirchPlanks, 4 = BirchLog, *
|
||||
JunglePlanks, 4 = JungleLog, *
|
||||
Stick, 4 = Planks, 2:2, 2:3
|
||||
Torch, 4 = Stick, 1:2 | Coal, 1:1
|
||||
Workbench = Planks, 1:1, 1:2, 2:1, 2:2
|
||||
Chest = Planks, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
|
||||
TrappedChest = TripWireHook, 1:1 | Chest, 2:1
|
||||
EnderChest = EyeOfEnder, 2:2 | Obsidian, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
|
||||
Furnace = Cobblestone, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Blocks
|
||||
#
|
||||
IronBlock = IronIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
GoldBlock = GoldIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
DiamondBlock = Diamond, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
LapisBlock = LapisLazuli, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
EmeraldBlock = Emerald, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
RedstoneBlock = RedstoneDust, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
QuartzBlock = NetherQuartz, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
NetherBrick = netherbrickitem, 1:1, 1:2, 2:1, 2:2
|
||||
Glowstone = GlowstoneDust, 1:1, 1:2, 2:1, 2:2
|
||||
Wool = String, 1:1, 1:2, 2:1, 2:2
|
||||
TNT = Gunpowder, 1:1, 3:1, 2:2, 1:3, 3:3 | Sand, 2:1, 1:2, 3:2, 2:3
|
||||
PillarQuartzBlock = QuartzSlab, 1:1, 1:2
|
||||
ChiseledQuartzBlock, 2 = QuartzBlock, 1:1, 1:2
|
||||
|
||||
# Slabs:
|
||||
StoneSlab, 6 = Stone, 1:1, 2:1, 3:1
|
||||
SandstoneSlab, 6 = Sandstone, 1:1, 2:1, 3:1
|
||||
WoodSlab, 6 = Planks, 1:1, 2:1, 3:1
|
||||
CobblestoneSlab, 6 = Cobblestone, 1:1, 2:1, 3:1
|
||||
BrickSlab, 6 = BrickBlock, 1:1, 2:1, 3:1
|
||||
StonebrickSlab, 6 = StoneBrick, 1:1, 2:1, 3:1
|
||||
NetherbrickSlab, 6 = NetherBrick, 1:1, 2:1, 3:1
|
||||
Quartzslab, 6 = QuartzBlock, 1:1, 2:1, 3:1
|
||||
snow, 6 = SnowBlock, 1:1, 2:1, 3:1
|
||||
|
||||
# Stairs:
|
||||
WoodStairs, 4 = Planks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
WoodStairs, 4 = Planks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
cobblestoneStairs, 4 = Cobblestone, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
cobblestoneStairs, 4 = Cobblestone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
BrickStairs, 4 = BrickBlock, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
BrickStairs, 4 = BrickBlock, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
SandstoneStairs, 4 = Sandstone, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
SandstoneStairs, 4 = Sandstone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
NetherBrickStairs, 4 = NetherBrick, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
quartzstairs, 4 = QuartzBlock, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
SnowBlock = SnowBall, 1:1, 1:2, 2:1, 2:2
|
||||
ClayBlock = Clay, 1:1, 1:2, 2:1, 2:2
|
||||
BrickBlock = Brick, 1:1, 1:2, 2:1, 2:2
|
||||
StoneBrick, 4 = Stone, 1:1, 1:2, 2:1, 2:2
|
||||
BookShelf = Planks, 1:1, 2:1, 3:1, 1:3, 2:3, 3:3 | Book, 1:2, 2:2, 3:2
|
||||
Sandstone, 4 = Sand, 1:1, 1:2, 2:1, 2:2
|
||||
SmoothSandstone, 4 = Sandstone, 1:1, 1:2, 2:1, 2:2
|
||||
OrnamentSandstone = SandstoneSlab, 1:1, 1:2
|
||||
JackOLantern = Pumpkin, 1:1 | Torch, 1:2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Tools
|
||||
#
|
||||
|
||||
# Axes:
|
||||
WoodenAxe = Stick, 2:2, 2:3 | Planks, 2:1, 1:1, 1:2
|
||||
WoodenAxe = Stick, 2:2, 2:3 | Planks, 2:1, 3:1, 3:2
|
||||
StoneAxe = Stick, 2:2, 2:3 | Cobblestone, 2:1, 1:1, 1:2
|
||||
StoneAxe = Stick, 2:2, 2:3 | Cobblestone, 2:1, 3:1, 3:2
|
||||
GoldenAxe = Stick, 2:2, 2:3 | GoldIngot, 2:1, 1:1, 1:2
|
||||
GoldenAxe = Stick, 2:2, 2:3 | GoldIngot, 2:1, 3:1, 3:2
|
||||
IronAxe = Stick, 2:2, 2:3 | IronIngot, 2:1, 1:1, 1:2
|
||||
IronAxe = Stick, 2:2, 2:3 | IronIngot, 2:1, 3:1, 3:2
|
||||
DiamondAxe = Stick, 2:2, 2:3 | Diamond, 2:1, 1:1, 1:2
|
||||
DiamondAxe = Stick, 2:2, 2:3 | Diamond, 2:1, 3:1, 3:2
|
||||
|
||||
# Pickaxes:
|
||||
WoodenPickaxe = Stick, 2:2, 2:3 | Planks, 1:1, 2:1, 3:1
|
||||
StonePickaxe = Stick, 2:2, 2:3 | Cobblestone, 1:1, 2:1, 3:1
|
||||
GoldenPickaxe = Stick, 2:2, 2:3 | GoldIngot, 1:1, 2:1, 3:1
|
||||
IronPickaxe = Stick, 2:2, 2:3 | IronIngot, 1:1, 2:1, 3:1
|
||||
DiamondPickaxe = Stick, 2:2, 2:3 | Diamond, 1:1, 2:1, 3:1
|
||||
|
||||
# Shovels:
|
||||
WoodenShovel = Stick, 2:2, 2:3 | Planks, 2:1
|
||||
StoneShovel = Stick, 2:2, 2:3 | Cobblestone, 2:1
|
||||
GoldenShovel = Stick, 2:2, 2:3 | GoldIngot, 2:1
|
||||
IronShovel = Stick, 2:2, 2:3 | IronIngot, 2:1
|
||||
DiamondShovel = Stick, 2:2, 2:3 | Diamond, 2:1
|
||||
|
||||
# Hoes:
|
||||
WoodenHoe = Stick, 2:2, 2:3 | Planks, 2:1, *:1
|
||||
StoneHoe = Stick, 2:2, 2:3 | Cobblestone, 2:1, *:1
|
||||
GoldenHoe = Stick, 2:2, 2:3 | GoldIngot, 2:1, *:1
|
||||
IronHoe = Stick, 2:2, 2:3 | IronIngot, 2:1, *:1
|
||||
DiamondHoe = Stick, 2:2, 2:3 | Diamond, 2:1, *:1
|
||||
|
||||
Lighter = IronIngot, 1:1 | Flint, 2:2
|
||||
Lighter = IronIngot, 2:1 | Flint, 1:2
|
||||
Bucket = IronIngot, 1:1, 2:2, 3:1
|
||||
Compass = IronIngot, 2:1, 1:2, 3:2, 2:3 | RedstoneDust, 2:2
|
||||
Map = Paper, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Compass, 2:2
|
||||
Watch = GoldIngot, 2:1, 1:2, 3:2, 2:3 | RedstoneDust, 2:2
|
||||
FishingRod = Stick, 1:3, 2:2, 3:1 | String, 3:2, 3:3
|
||||
FishingRod = Stick, 3:3, 2:2, 1:1 | String, 1:2, 1:3
|
||||
Shears = IronIngot, 1:1, 2:2
|
||||
Shears = IronIngot, 2:1, 1:2
|
||||
FireCharge = BlazePowder, * | Coal, * | Gunpowder, *
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Weapons
|
||||
#
|
||||
WoodenSword = Stick, 2:3 | Planks, 2:1, 2:2
|
||||
StoneSword = Stick, 2:3 | Cobblestone, 2:1, 2:2
|
||||
GoldenSword = Stick, 2:3 | GoldIngot, 2:1, 2:2
|
||||
IronSword = Stick, 2:3 | IronIngot, 2:1, 2:2
|
||||
DiamondSword = Stick, 2:3 | Diamond, 2:1, 2:2
|
||||
Bow = Stick, 2:1, 1:2, 2:3 | String, 3:1, 3:2, 3:3
|
||||
Bow = Stick, 2:1, 3:2, 2:3 | String, 1:1, 1:2, 1:3
|
||||
Arrow, 4 = Flint, 1:1 | Stick, 1:2 | Feather, 1:3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Armor
|
||||
#
|
||||
|
||||
# Helmets:
|
||||
LeatherHelmet = Leather, 1:1, 2:1, 3:1, 1:2, 3:2
|
||||
ChainmailHelmet = Fire, 1:1, 2:1, 3:1, 1:2, 3:2
|
||||
GoldenHelmet = GoldIngot, 1:1, 2:1, 3:1, 1:2, 3:2
|
||||
IronHelmet = IronIngot, 1:1, 2:1, 3:1, 1:2, 3:2
|
||||
DiamondHelmet = Diamond, 1:1, 2:1, 3:1, 1:2, 3:2
|
||||
|
||||
# Chestplates:
|
||||
LeatherChestplate = Leather, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
ChainmailChestplate = Fire, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
GoldenChestplate = GoldIngot, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
IronChestplate = IronIngot, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
DiamondChestplate = Diamond, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
|
||||
# Leggins:
|
||||
LeatherPants = Leather, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
|
||||
ChainmailPants = Fire, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
|
||||
GoldenPants = GoldIngot, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
|
||||
IronPants = IronIngot, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
|
||||
DiamondPants = Diamond, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
|
||||
|
||||
# Boots:
|
||||
LeatherBoots = Leather, 1:1, 3:1, 1:2, 3:2
|
||||
ChainmailBoots = Fire, 1:1, 3:1, 1:2, 3:2
|
||||
GoldenBoots = GoldIngot, 1:1, 3:1, 1:2, 3:2
|
||||
IronBoots = IronIngot, 1:1, 3:1, 1:2, 3:2
|
||||
DiamondBoots = Diamond, 1:1, 3:1, 1:2, 3:2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Transportation
|
||||
#
|
||||
CarrotOnAStick = FishingRod, 1:2 | Carrot, 2:3
|
||||
Minecart = IronIngot, 1:1, 3:1, 1:2, 2:2, 3:2
|
||||
PoweredMinecart = Minecart, * | Furnace, *
|
||||
StorageMinecart = Minecart, * | Chest, *
|
||||
TNTMinecart = Minecart, * | TNT, *
|
||||
hopperminecart = Minecart, * | Hopper, *
|
||||
Rails, 16 = IronIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 3:3 | Stick, 2:2
|
||||
PoweredRail, 6 = GoldIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 3:3 | Stick, 2:2 | RedstoneDust, 2:3
|
||||
DetectorRail, 6 = IronIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 3:3 | StonePlate, 2:2 | RedstoneDust, 2:3
|
||||
Boat = Planks, 1:1, 3:1, 1:2, 2:2, 3:2
|
||||
ActivatorRail, 6 = IronIngot, 1:1, 1:2, 1:3, 3:1, 3:2, 3:3 | Stick, 2:1, 2:3 | RedstoneTorchon, 2:2
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Mechanisms
|
||||
#
|
||||
WoodenDoor = Planks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
IronDoor = IronIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
TrapDoor, 2 = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
WoodPlate = Planks, 1:1, 2:1
|
||||
StonePlate = Stone, 1:1, 2:1
|
||||
StoneButton = Stone, 1:1
|
||||
WoodenButton = Planks, 1:1
|
||||
RedstoneTorchOn = Stick, 1:2 | RedstoneDust, 1:1
|
||||
Lever = Cobblestone, 1:2 | Stick, 1:1
|
||||
NoteBlock = Planks, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | RedstoneDust, 2:2
|
||||
Jukebox = Planks, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Diamond, 2:2
|
||||
Dispenser = Cobblestone, 1:1, 1:2, 1:3, 2:1, 3:1, 3:2, 3:3 | RedstoneDust, 2:3 | Bow, 2:2
|
||||
Dropper = Cobblestone, 1:1, 2:1, 3:1, 1:2, 1:3, 3:2, 3:3 | Hopper, 2:2 | RedstoneDust, 2:3
|
||||
Repeater = Stone, 1:2, 2:2, 3:2 | RedstoneTorchOn, 1:1, 3:1 | RedstoneDust, 2:1
|
||||
Comparator = RedstoneTorchOn, 2:1, 1:2, 3:2 | NetherQuartz, 2:2 | Stone, 1:3, 2:3, 3:3
|
||||
DaylightSensor = Glass, 1:1, 2:1, 3:1 | NetherQuartz, 1:2, 2:2, 3:2 | Woodslab, 1:3, 2:3, 3:3
|
||||
Hopper = Ironbars, 1:1, 3:1, 1:2, 3:2, 2:3 | Chest, 2:2
|
||||
Piston = Planks, 1:1, 2:1, 3:1 | RedstoneDust, 2:3 | Cobblestone, 1:2, 3:2, 1:3, 3:3 | IronIngot, 2:2
|
||||
StickyPiston = Piston, * | SlimeBall, *
|
||||
RedstoneLamp = RedstoneDust, 2:1, 1:2, 3:2, 2:3 | Glowstone, 2:2
|
||||
tripwirehook, 2 = planks, 2:3 | stick, 2:2 | ironbar, 2:1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Food
|
||||
#
|
||||
Bowl, 4 = Planks, 1:1, 2:2, 3:1
|
||||
MushroomStew = Bowl, * | BrownMushroom, * | RedMushroom, *
|
||||
Bread = Wheat, 1:1, 2:1, 3:1
|
||||
Sugar = Sugarcane, *
|
||||
Cake = MilkBucket, 1:1, 2:1, 3:1 | Sugar, 1:2, 3:2 | Egg, 2:2 | Wheat, 1:3, 2:3, 3:3
|
||||
Cookie = Wheat, *, * | CocoaBeans, *
|
||||
GoldenApple = RedApple, 2:2 | GoldNugget, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
|
||||
EnchantedGoldenApple = RedApple, 2:2 | GoldBlock, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
|
||||
Melon = MelonSlice, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
MelonSeeds = MelonSlice, *
|
||||
PumpkinSeeds, 4 = Pumpkin, *
|
||||
PumpkinPie = Pumpkin, * | Sugar, * | egg, *
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Miscellaneous
|
||||
#
|
||||
|
||||
# Minerals:
|
||||
IronIngot, 9 = IronBlock, *
|
||||
GoldIngot, 9 = GoldBlock, *
|
||||
Diamond, 9 = DiamondBlock, *
|
||||
LapisLazuli, 9 = LapisBlock, *
|
||||
Emerald, 9 = EmeraldBlock, *
|
||||
RedstoneDust, 9 = RedstoneBlock, *
|
||||
|
||||
Painting = Stick, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Wool, 2:2
|
||||
ItemFrame = Stick, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Leather, 2:2
|
||||
Sign = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2 | Stick, 2:3
|
||||
Ladder, 3 = Stick, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 3:3
|
||||
GlassPane, 16 = Glass, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
IronBars, 16 = IronIngot, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
Paper, 3 = Sugarcane, 1:1, 2:1, 3:1
|
||||
Book = Paper, *, *, * | leather, *
|
||||
Bookandquill = Book, * | feather, * | inksac, *
|
||||
Fence, 2 = Stick, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
Cobblestonewall, 6 = cobblestone, 1:2, 1:3, 2:2, 2:3, 3:2, 3:3
|
||||
mossycobblestonewall, 6 = mossycobblestone, 1:2, 1:3, 2:2, 2:3, 3:2, 3:3
|
||||
NetherBrickFence, 6 = NetherBrick, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
FenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | Planks, 2:1, 2:2
|
||||
Bed = Planks, 1:2, 2:2, 3:2 | Wool, 1:1, 2:1, 3:1
|
||||
GoldIngot = GoldNugget, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
EyeOfEnder = EnderPearl, * | BlazePowder, *
|
||||
Beacon = Glass, 1:1, 1:2, 2:1, 3:1, 3:2 | Obsidian, 1:3, 2:3, 3:3 | NetherStar, 2:2
|
||||
Anvil = IronBlock, 1:1, 2:1, 3:1 | IronIngot, 2:2, 1:3, 2:3, 3:3
|
||||
FlowerPot = Brick, 1:2, 2:3, 3:2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Dyes
|
||||
#
|
||||
|
||||
WhiteDye, 3 = Bone, *
|
||||
RedDye, 2 = Rose, *
|
||||
YellowDye, 2 = Flower, *
|
||||
|
||||
# Color mixing, duals:
|
||||
OrangeDye, 2 = YellowDye, * | RedDye, *
|
||||
CyanDye, 2 = GreenDye, * | BlueDye, *
|
||||
PurpleDye, 2 = RedDye, * | BlueDye, *
|
||||
GrayDye, 2 = BlackDye, * | WhiteDye, *
|
||||
LtBlueDye, 2 = BlueDye, * | WhiteDye, *
|
||||
PinkDye, 2 = RedDye, * | WhiteDye, *
|
||||
LimeDye, 2 = GreenDye, * | WhiteDye, *
|
||||
MagentaDye, 2 = PurpleDye, * | PinkDye, *
|
||||
LtGrayDye, 2 = GrayDye, * | WhiteDye, *
|
||||
|
||||
# triplets:
|
||||
LtGrayDye, 3 = BlackDye, * | WhiteDye, *, *
|
||||
MagentaDye, 3 = BlueDye, * | PinkDye, * | RedDye, *
|
||||
|
||||
# quads:
|
||||
MagentaDye, 4 = BlueDye, * | WhiteDye, * | RedDye, *, *
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Colored wool:
|
||||
#
|
||||
WhiteWool = Wool, * | BoneMeal, *
|
||||
OrangeWool = Wool, * | OrangeDye, *
|
||||
MagentaWool = Wool, * | MagentaDye, *
|
||||
LightBlueWool = Wool, * | LightBlueDye, *
|
||||
YellowWool = Wool, * | YellowDye, *
|
||||
LimeWool = Wool, * | LimeDye, *
|
||||
PinkWool = Wool, * | PinkDye, *
|
||||
GrayWool = Wool, * | GrayDye, *
|
||||
LightGrayWool = Wool, * | LightGrayDye, *
|
||||
CyanWool = Wool, * | CyanDye, *
|
||||
VioletWool = Wool, * | VioletDye, *
|
||||
BlueWool = Wool, * | BlueDye, *
|
||||
BrownWool = Wool, * | BrownDye, *
|
||||
GreenWool = Wool, * | GreenDye, *
|
||||
RedWool = Wool, * | RedDye, *
|
||||
BlackWool = Wool, * | BlackDye, *
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
# Enchantment & Brewing
|
||||
#
|
||||
GlassBottle, 3 = Glass, 1:1, 2:2, 3:1
|
||||
Cauldron = IronIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 2:3, 3:3
|
||||
BrewingStand = Cobblestone, 1:2, 2:2, 3:2 | BlazeRod, 2:1
|
||||
BlazePowder, 2 = BlazeRod, *
|
||||
MagmaCream = SlimeBall, * | BlazePowder, *
|
||||
FermentedSpiderEye = SpiderEye, * | Sugar, * | BrownMushroom, *
|
||||
GlisteringMelon = MelonSlice, * | GoldNugget, *
|
||||
GoldNugget, 9 = GoldIngot, *
|
||||
EnchantmentTable = Obsidian, 1:3, 2:3, 3:3, 2:2 | Diamond, 1:2, 3:2 | Book, 2:1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,75 +1,75 @@
|
||||
#*****************#
|
||||
# Furnace Recipes #
|
||||
#*****************#
|
||||
#
|
||||
#
|
||||
#******************************************************#
|
||||
# Basic Notation Help
|
||||
#
|
||||
# **** Item Definition ****
|
||||
# An Item is defined by an Item Type, an amount (and damage)
|
||||
# The damage is optional, and if not specified it's assumed to be 0
|
||||
#
|
||||
# -Cactus Green:
|
||||
# 351 : 1 ( : 2 )
|
||||
# ItemType : Amount ( : Damage )
|
||||
#
|
||||
#
|
||||
# **** Recipe and result ****
|
||||
#
|
||||
# 4:1@200=1:1 -> Produces 1 smooth stone from 1 cobblestone in 200 ticks (10 seconds)
|
||||
#
|
||||
# 4 : 1 @ 200 = 1 : 1
|
||||
# ItemType : Amount @ ticks = ItemID : Amount
|
||||
#
|
||||
#
|
||||
# **** Fuel ****
|
||||
#
|
||||
# !17:1 = 300 -> 1 Wood burns for 300 ticks (15 s)
|
||||
#
|
||||
# ! 17 : 1 = 300
|
||||
# Fuel ItemType : Amount = ticks
|
||||
#
|
||||
#******************************************************#
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#--------------------------
|
||||
# Smelting recipes
|
||||
|
||||
4:1 @ 200 = 1:1 # 1 Cobblestone -> 1 Rock
|
||||
15:1 @ 200 = 265:1 # 1 Iron Ore -> 1 Iron Ingot
|
||||
14:1 @ 200 = 266:1 # 1 Gold Ore -> 1 Gold Ingot
|
||||
153:1 @ 200 = 406:1 # 1 Quartz Ore -> 1 Quartz
|
||||
12:1 @ 200 = 20:1 # 1 Sand -> 1 Glass
|
||||
319:1 @ 200 = 320:1 # 1 Raw Pork -> 1 Cooked Pork
|
||||
363:1 @ 200 = 364:1 # 1 Raw Beef -> 1 Cooked Beef (steak)
|
||||
365:1 @ 200 = 366:1 # 1 Raw Chicken -> 1 Cooked Chicken
|
||||
337:1 @ 200 = 336:1 # 1 Clay -> 1 Clay Brick
|
||||
87:1 @ 200 = 405:1 # 1 NetherRack -> 1 NetherBrick
|
||||
349:1 @ 200 = 350:1 # 1 Raw Fish -> 1 Cooked Fish
|
||||
17:1 @ 200 = 263:1:1 # 1 Log -> 1 Charcoal
|
||||
81:1 @ 200 = 351:1:2 # 1 Cactus -> 1 Green Dye
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#--------------------------
|
||||
# Fuels
|
||||
|
||||
! 263:1 = 1600 # 1 Charcoal -> 80 sec
|
||||
! 42:126:1 = 150 # 1 Halfslab -> 7.5 seconds
|
||||
! 5:1 = 300 # 1 Planks -> 15 sec
|
||||
! 280:1 = 100 # 1 Stick -> 5 sec
|
||||
! 85:1 = 300 # 1 Fence -> 15 sec
|
||||
! 53:1 = 300 # 1 Wooden Stairs -> 15 sec
|
||||
! 58:1 = 300 # 1 Crafting Table -> 15 sec
|
||||
! 47:1 = 300 # 1 Bookshelf -> 15 sec
|
||||
! 54:1 = 300 # 1 Chest -> 15 sec
|
||||
! 84:1 = 300 # 1 Jukebox -> 15 sec
|
||||
! 327:1 = 200000 # 1 Lava Bucket -> 1000 sec
|
||||
! 17:1 = 300 # 1 Wood -> 15 sec
|
||||
! 6:1 = 100 # 1 Sapling -> 5 sec
|
||||
#*****************#
|
||||
# Furnace Recipes #
|
||||
#*****************#
|
||||
#
|
||||
#
|
||||
#******************************************************#
|
||||
# Basic Notation Help
|
||||
#
|
||||
# **** Item Definition ****
|
||||
# An Item is defined by an Item Type, an amount (and damage)
|
||||
# The damage is optional, and if not specified it's assumed to be 0
|
||||
#
|
||||
# -Cactus Green:
|
||||
# 351 : 1 ( : 2 )
|
||||
# ItemType : Amount ( : Damage )
|
||||
#
|
||||
#
|
||||
# **** Recipe and result ****
|
||||
#
|
||||
# 4:1@200=1:1 -> Produces 1 smooth stone from 1 cobblestone in 200 ticks (10 seconds)
|
||||
#
|
||||
# 4 : 1 @ 200 = 1 : 1
|
||||
# ItemType : Amount @ ticks = ItemID : Amount
|
||||
#
|
||||
#
|
||||
# **** Fuel ****
|
||||
#
|
||||
# !17:1 = 300 -> 1 Wood burns for 300 ticks (15 s)
|
||||
#
|
||||
# ! 17 : 1 = 300
|
||||
# Fuel ItemType : Amount = ticks
|
||||
#
|
||||
#******************************************************#
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#--------------------------
|
||||
# Smelting recipes
|
||||
|
||||
4:1 @ 200 = 1:1 # 1 Cobblestone -> 1 Rock
|
||||
15:1 @ 200 = 265:1 # 1 Iron Ore -> 1 Iron Ingot
|
||||
14:1 @ 200 = 266:1 # 1 Gold Ore -> 1 Gold Ingot
|
||||
153:1 @ 200 = 406:1 # 1 Quartz Ore -> 1 Quartz
|
||||
12:1 @ 200 = 20:1 # 1 Sand -> 1 Glass
|
||||
319:1 @ 200 = 320:1 # 1 Raw Pork -> 1 Cooked Pork
|
||||
363:1 @ 200 = 364:1 # 1 Raw Beef -> 1 Cooked Beef (steak)
|
||||
365:1 @ 200 = 366:1 # 1 Raw Chicken -> 1 Cooked Chicken
|
||||
337:1 @ 200 = 336:1 # 1 Clay -> 1 Clay Brick
|
||||
87:1 @ 200 = 405:1 # 1 NetherRack -> 1 NetherBrick
|
||||
349:1 @ 200 = 350:1 # 1 Raw Fish -> 1 Cooked Fish
|
||||
17:1 @ 200 = 263:1:1 # 1 Log -> 1 Charcoal
|
||||
81:1 @ 200 = 351:1:2 # 1 Cactus -> 1 Green Dye
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#--------------------------
|
||||
# Fuels
|
||||
|
||||
! 263:1 = 1600 # 1 Charcoal -> 80 sec
|
||||
! 42:126:1 = 150 # 1 Halfslab -> 7.5 seconds
|
||||
! 5:1 = 300 # 1 Planks -> 15 sec
|
||||
! 280:1 = 100 # 1 Stick -> 5 sec
|
||||
! 85:1 = 300 # 1 Fence -> 15 sec
|
||||
! 53:1 = 300 # 1 Wooden Stairs -> 15 sec
|
||||
! 58:1 = 300 # 1 Crafting Table -> 15 sec
|
||||
! 47:1 = 300 # 1 Bookshelf -> 15 sec
|
||||
! 54:1 = 300 # 1 Chest -> 15 sec
|
||||
! 84:1 = 300 # 1 Jukebox -> 15 sec
|
||||
! 327:1 = 200000 # 1 Lava Bucket -> 1000 sec
|
||||
! 17:1 = 300 # 1 Wood -> 15 sec
|
||||
! 6:1 = 100 # 1 Sapling -> 5 sec
|
||||
|
@ -1,17 +1,17 @@
|
||||
[Admins]
|
||||
Permissions=*
|
||||
Color=c
|
||||
|
||||
[Mods]
|
||||
Color=5
|
||||
Inherits=Vips
|
||||
Permissions=core.time,core.item
|
||||
|
||||
[Vips]
|
||||
Permissions=core.teleport
|
||||
Color=2
|
||||
Inherits=Default
|
||||
|
||||
[Default]
|
||||
Permissions=core.build,core.help,core.playerlist,core.pluginlist,core.spawn
|
||||
[Admins]
|
||||
Permissions=*
|
||||
Color=c
|
||||
|
||||
[Mods]
|
||||
Color=5
|
||||
Inherits=Vips
|
||||
Permissions=core.time,core.item
|
||||
|
||||
[Vips]
|
||||
Permissions=core.teleport
|
||||
Color=2
|
||||
Inherits=Default
|
||||
|
||||
[Default]
|
||||
Permissions=core.build,core.help,core.playerlist,core.pluginlist,core.spawn
|
||||
Color=7
|
@ -1,22 +1,22 @@
|
||||
# This is a valgrind suppressions file for running helgrind on MCServer
|
||||
# Use by adding "--suppressions=hg.supp" to the helgrind commandline
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# This covers GCC bug 40518, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40518
|
||||
# "Erasing an empty string causes a global value write / race condition warning in helgrind"
|
||||
# Original suppression authored by Jonathan Wakely: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40518#c20
|
||||
# Modified by Mattes to match the mangled function name used on Ubuntu
|
||||
|
||||
{
|
||||
libstdcxx_std_string_race_pr40518
|
||||
Helgrind:Race
|
||||
fun:_ZNSs9_M_mutateEjjj
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
# This is a valgrind suppressions file for running helgrind on MCServer
|
||||
# Use by adding "--suppressions=hg.supp" to the helgrind commandline
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# This covers GCC bug 40518, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40518
|
||||
# "Erasing an empty string causes a global value write / race condition warning in helgrind"
|
||||
# Original suppression authored by Jonathan Wakely: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40518#c20
|
||||
# Modified by Mattes to match the mangled function name used on Ubuntu
|
||||
|
||||
{
|
||||
libstdcxx_std_string_race_pr40518
|
||||
Helgrind:Race
|
||||
fun:_ZNSs9_M_mutateEjjj
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
1086
MCServer/items.ini
1086
MCServer/items.ini
File diff suppressed because it is too large
Load Diff
@ -1,111 +1,111 @@
|
||||
[Spider]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=10
|
||||
|
||||
[Chicken]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=4
|
||||
|
||||
[Cow]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=10
|
||||
|
||||
[Pig]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=10
|
||||
|
||||
[Sheep]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=8
|
||||
|
||||
[Squid]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=10
|
||||
|
||||
[Enderman]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=4.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=40
|
||||
|
||||
[Zombiepigman]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=5.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=20
|
||||
|
||||
[Cavespider]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=2.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=12
|
||||
|
||||
[Creeper]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=0.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=20
|
||||
|
||||
[Ghast]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=0.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=10
|
||||
|
||||
[Silverfish]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=8
|
||||
|
||||
[Skeleton]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=4.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=20
|
||||
|
||||
[Slime]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=10.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=32
|
||||
|
||||
[Spider]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=2.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=16
|
||||
|
||||
[Zombie]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=4.0
|
||||
SightDistance=25.0
|
||||
[Spider]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=10
|
||||
|
||||
[Chicken]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=4
|
||||
|
||||
[Cow]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=10
|
||||
|
||||
[Pig]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=10
|
||||
|
||||
[Sheep]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=8
|
||||
|
||||
[Squid]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=10
|
||||
|
||||
[Enderman]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=4.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=40
|
||||
|
||||
[Zombiepigman]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=5.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=20
|
||||
|
||||
[Cavespider]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=2.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=12
|
||||
|
||||
[Creeper]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=0.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=20
|
||||
|
||||
[Ghast]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=0.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=10
|
||||
|
||||
[Silverfish]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=1.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=8
|
||||
|
||||
[Skeleton]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=4.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=20
|
||||
|
||||
[Slime]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=10.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=32
|
||||
|
||||
[Spider]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=2.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=16
|
||||
|
||||
[Zombie]
|
||||
AttackRange=5.0
|
||||
AttackRate=1
|
||||
AttackDamage=4.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=20
|
@ -1,31 +1,31 @@
|
||||
; This is the main server configuration
|
||||
; For help, please visit the Wiki page: http://www.mc-server.org/wiki/doku.php?id=configure:settings.ini
|
||||
; Most of these settings can also be set using the webadmin interface, if it is enabled.
|
||||
|
||||
[Server]
|
||||
Port=25565
|
||||
MaxPlayers=100
|
||||
Description=MCServer - in C++
|
||||
DefaultViewDistance=9
|
||||
|
||||
[Worlds]
|
||||
DefaultWorld=world
|
||||
|
||||
[Plugins]
|
||||
; Plugin=Debuggers
|
||||
; Plugin=DiamondMover
|
||||
; Plugin=HookNotify
|
||||
Plugin=Core
|
||||
Plugin=ChunkWorx
|
||||
Plugin=ChatLog
|
||||
|
||||
[Monsters]
|
||||
AnimalsOn=0
|
||||
AnimalSpawnInterval=10
|
||||
Types=Spider,Chicken,Cow,Pig,Sheep,Squid,Enderman,Zombiepigman,Cavespider,Creeper,Ghast,Silverfish,Skeleton,Slime,Spider,Zombie
|
||||
|
||||
[Authentication]
|
||||
Server=session.minecraft.net
|
||||
Address=/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%
|
||||
Authenticate=0
|
||||
|
||||
; This is the main server configuration
|
||||
; For help, please visit the Wiki page: http://www.mc-server.org/wiki/doku.php?id=configure:settings.ini
|
||||
; Most of these settings can also be set using the webadmin interface, if it is enabled.
|
||||
|
||||
[Server]
|
||||
Port=25565
|
||||
MaxPlayers=100
|
||||
Description=MCServer - in C++
|
||||
DefaultViewDistance=9
|
||||
|
||||
[Worlds]
|
||||
DefaultWorld=world
|
||||
|
||||
[Plugins]
|
||||
; Plugin=Debuggers
|
||||
; Plugin=DiamondMover
|
||||
; Plugin=HookNotify
|
||||
Plugin=Core
|
||||
Plugin=ChunkWorx
|
||||
Plugin=ChatLog
|
||||
|
||||
[Monsters]
|
||||
AnimalsOn=0
|
||||
AnimalSpawnInterval=10
|
||||
Types=Spider,Chicken,Cow,Pig,Sheep,Squid,Enderman,Zombiepigman,Cavespider,Creeper,Ghast,Silverfish,Skeleton,Slime,Spider,Zombie
|
||||
|
||||
[Authentication]
|
||||
Server=session.minecraft.net
|
||||
Address=/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%
|
||||
Authenticate=0
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
[Terrain]
|
||||
HeightFreq1=0.100000
|
||||
HeightFreq2=1.000000
|
||||
HeightFreq3=2.000000
|
||||
HeightAmp1=1.000000
|
||||
HeightAmp2=0.500000
|
||||
HeightAmp3=0.500000
|
||||
|
||||
[Terrain]
|
||||
HeightFreq1=0.100000
|
||||
HeightFreq2=1.000000
|
||||
HeightFreq3=2.000000
|
||||
HeightAmp1=1.000000
|
||||
HeightAmp2=0.500000
|
||||
HeightAmp3=0.500000
|
||||
|
||||
|
@ -1,23 +1,23 @@
|
||||
[FakeTruth]
|
||||
Groups=Admins
|
||||
|
||||
[Duralex]
|
||||
Groups=Admins
|
||||
|
||||
[Luthrandel]
|
||||
Groups=Admins
|
||||
|
||||
[cruisecho]
|
||||
Groups=Admins
|
||||
|
||||
[Kwen]
|
||||
Groups=Admins
|
||||
|
||||
[aloe_vera]
|
||||
Groups=Admins
|
||||
|
||||
[xoft]
|
||||
Groups=Admins
|
||||
|
||||
[Player]
|
||||
[FakeTruth]
|
||||
Groups=Admins
|
||||
|
||||
[Duralex]
|
||||
Groups=Admins
|
||||
|
||||
[Luthrandel]
|
||||
Groups=Admins
|
||||
|
||||
[cruisecho]
|
||||
Groups=Admins
|
||||
|
||||
[Kwen]
|
||||
Groups=Admins
|
||||
|
||||
[aloe_vera]
|
||||
Groups=Admins
|
||||
|
||||
[xoft]
|
||||
Groups=Admins
|
||||
|
||||
[Player]
|
||||
Groups=Admins
|
@ -1,6 +1,6 @@
|
||||
[WebAdmin]
|
||||
Enabled=1
|
||||
Port=8081
|
||||
|
||||
[User:admin]
|
||||
[WebAdmin]
|
||||
Enabled=1
|
||||
Port=8081
|
||||
|
||||
[User:admin]
|
||||
Password=admin
|
File diff suppressed because one or more lines are too long
@ -1,146 +1,146 @@
|
||||
@echo off
|
||||
:: Nightbbuild2008.cmd
|
||||
:: This script is run every night to produce a new version of MCServer, backup its PDB files and upload the packages to web.
|
||||
:: These sub-scripts are used:
|
||||
:: - WCRev.cmd together with subwcrev templating to obtain the version number as an environment var
|
||||
:: - UploadVersion.ftp FTP command template for uploading the version to the web (not included in the SVN, because it contains confidential passwords! Use your own :)
|
||||
:: When run without parameters, this script pauses at the end and waits for a keypress.
|
||||
:: To run in an automated scheduler, add any parameter to disable waiting for a keystroke
|
||||
::
|
||||
:: This script expects a few tools on specific paths, you can pass the correct paths for your system as env vars "zip", "vc" and "tsvn"
|
||||
|
||||
|
||||
:: 7-zip executable (by default it should be on PATH):
|
||||
if %zip%a == a set zip=7z
|
||||
|
||||
:: Visual C++ compiler executable name:
|
||||
if %vc%a == a set vc="vcbuild.exe"
|
||||
|
||||
:: TortoiseProc executable (for updating to the latest version):
|
||||
if %tsvn%a== a set tsvn="c:\program files\tortoisesvn\bin\tortoiseproc.exe"
|
||||
|
||||
:: Subwcrev (from TortoiseSVN, for querying revision number; by default in PATH):
|
||||
if %subwcrev%a == a set subwcrev=subwcrev
|
||||
|
||||
|
||||
|
||||
|
||||
echo Performing nightbuild of MC-Server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
set DONOTPAUSE=y
|
||||
|
||||
:: Update the sources to the latest revision:
|
||||
del source\Bindings.cpp
|
||||
del source\Bindings.h
|
||||
start "tsvn src" /b /min /wait %tsvn% /command:update /path:. /closeonend:1
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
:: Copy all *.template files into their non-template versions, substituting SVN keywords:
|
||||
for /r %%X in (*.template) do (
|
||||
%subwcrev% . "%%X" "%%~dpX%%~nX"
|
||||
if errorlevel 1 goto haderror
|
||||
)
|
||||
|
||||
|
||||
:: Get the revision number into WCREV env var
|
||||
call Install\WCVersion.cmd
|
||||
echo WCREV = %WCREV%
|
||||
|
||||
|
||||
:: Test if the version is already present
|
||||
if exist Install\MCServer_Win_%WCREV%.7z (
|
||||
echo Latest version already present, bailing out
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
|
||||
:: Update Bindings.cpp
|
||||
del source\Bindings.cpp
|
||||
del source\Bindings.h
|
||||
echo Updating Lua bindings
|
||||
set ALLTOLUA_WAIT=N
|
||||
cd source
|
||||
call AllToLua.bat
|
||||
cd ..
|
||||
|
||||
|
||||
|
||||
|
||||
:: Compile using VC2008 Express. Do a full rebuild.
|
||||
echo Setting up VS environment...
|
||||
call "%VS90COMNTOOLS%\vsvars32.bat"
|
||||
echo Compiling MCServer...
|
||||
title MCS Nightbuild
|
||||
start "vc" /b /wait /low /min %vc% /r vc2008\MCServer.sln "Release|Win32"
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Use 7-zip to compress the resulting files into a single file:
|
||||
:: Note: the output filename here must be the same as in the upload_win.ftp.template script
|
||||
copy MCServer\MCServer.exe Install\MCServer.exe
|
||||
cd Install
|
||||
%zip% a -mx9 -y MCServer_Win_%WCREV%.7z -scsWIN @Zip2008.list
|
||||
if errorlevel 1 goto haderror
|
||||
cd ..
|
||||
|
||||
:: Also pack PDBs into a separate archive:
|
||||
:: Note: the output filename here must be the same as in the upload_win.ftp.template script
|
||||
%zip% a -mx9 -y Install\MCServer_Win_%WCREV%_PDBs.7z -scsWIN @Install\Zip2008_PDBs.list
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: upload to the FTP:
|
||||
:upload
|
||||
if "a%ftppass%" == "a" (
|
||||
echo You need to set FTP password in the ftppass environment variable to upload the files
|
||||
goto end
|
||||
)
|
||||
if "a%ftpuser%" == "a" (
|
||||
echo You need to set FTP username in the ftpuser environment variable to upload the files
|
||||
goto end
|
||||
)
|
||||
if "a%ftpsite%" == "a" (
|
||||
echo You need to set FTP server in the ftpsite environment variable to upload the files
|
||||
goto end
|
||||
)
|
||||
ncftpput -p %ftppass% -u %ftpuser% -T temp_ %ftpsite% / Install\MCServer_Win_%WCREV%.7z
|
||||
if errorlevel 1 goto haderror
|
||||
ncftpput -p %ftppass% -u %ftpuser% -T temp_ %ftpsite% /PDBs Install\MCServer_Win_%WCREV%_PDBs.7z
|
||||
if errorlevel 1 goto haderror
|
||||
echo Upload finished.
|
||||
|
||||
|
||||
|
||||
|
||||
goto end
|
||||
|
||||
|
||||
|
||||
|
||||
:haderror
|
||||
echo an error was encountered, check command output above
|
||||
pause
|
||||
goto finished
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:end
|
||||
if "a%1" == "a" pause
|
||||
|
||||
|
||||
|
||||
@echo off
|
||||
:: Nightbbuild2008.cmd
|
||||
:: This script is run every night to produce a new version of MCServer, backup its PDB files and upload the packages to web.
|
||||
:: These sub-scripts are used:
|
||||
:: - WCRev.cmd together with subwcrev templating to obtain the version number as an environment var
|
||||
:: - UploadVersion.ftp FTP command template for uploading the version to the web (not included in the SVN, because it contains confidential passwords! Use your own :)
|
||||
:: When run without parameters, this script pauses at the end and waits for a keypress.
|
||||
:: To run in an automated scheduler, add any parameter to disable waiting for a keystroke
|
||||
::
|
||||
:: This script expects a few tools on specific paths, you can pass the correct paths for your system as env vars "zip", "vc" and "tsvn"
|
||||
|
||||
|
||||
:: 7-zip executable (by default it should be on PATH):
|
||||
if %zip%a == a set zip=7z
|
||||
|
||||
:: Visual C++ compiler executable name:
|
||||
if %vc%a == a set vc="vcbuild.exe"
|
||||
|
||||
:: TortoiseProc executable (for updating to the latest version):
|
||||
if %tsvn%a== a set tsvn="c:\program files\tortoisesvn\bin\tortoiseproc.exe"
|
||||
|
||||
:: Subwcrev (from TortoiseSVN, for querying revision number; by default in PATH):
|
||||
if %subwcrev%a == a set subwcrev=subwcrev
|
||||
|
||||
|
||||
|
||||
|
||||
echo Performing nightbuild of MC-Server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
set DONOTPAUSE=y
|
||||
|
||||
:: Update the sources to the latest revision:
|
||||
del source\Bindings.cpp
|
||||
del source\Bindings.h
|
||||
start "tsvn src" /b /min /wait %tsvn% /command:update /path:. /closeonend:1
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
:: Copy all *.template files into their non-template versions, substituting SVN keywords:
|
||||
for /r %%X in (*.template) do (
|
||||
%subwcrev% . "%%X" "%%~dpX%%~nX"
|
||||
if errorlevel 1 goto haderror
|
||||
)
|
||||
|
||||
|
||||
:: Get the revision number into WCREV env var
|
||||
call Install\WCVersion.cmd
|
||||
echo WCREV = %WCREV%
|
||||
|
||||
|
||||
:: Test if the version is already present
|
||||
if exist Install\MCServer_Win_%WCREV%.7z (
|
||||
echo Latest version already present, bailing out
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
|
||||
:: Update Bindings.cpp
|
||||
del source\Bindings.cpp
|
||||
del source\Bindings.h
|
||||
echo Updating Lua bindings
|
||||
set ALLTOLUA_WAIT=N
|
||||
cd source
|
||||
call AllToLua.bat
|
||||
cd ..
|
||||
|
||||
|
||||
|
||||
|
||||
:: Compile using VC2008 Express. Do a full rebuild.
|
||||
echo Setting up VS environment...
|
||||
call "%VS90COMNTOOLS%\vsvars32.bat"
|
||||
echo Compiling MCServer...
|
||||
title MCS Nightbuild
|
||||
start "vc" /b /wait /low /min %vc% /r vc2008\MCServer.sln "Release|Win32"
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Use 7-zip to compress the resulting files into a single file:
|
||||
:: Note: the output filename here must be the same as in the upload_win.ftp.template script
|
||||
copy MCServer\MCServer.exe Install\MCServer.exe
|
||||
cd Install
|
||||
%zip% a -mx9 -y MCServer_Win_%WCREV%.7z -scsWIN @Zip2008.list
|
||||
if errorlevel 1 goto haderror
|
||||
cd ..
|
||||
|
||||
:: Also pack PDBs into a separate archive:
|
||||
:: Note: the output filename here must be the same as in the upload_win.ftp.template script
|
||||
%zip% a -mx9 -y Install\MCServer_Win_%WCREV%_PDBs.7z -scsWIN @Install\Zip2008_PDBs.list
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: upload to the FTP:
|
||||
:upload
|
||||
if "a%ftppass%" == "a" (
|
||||
echo You need to set FTP password in the ftppass environment variable to upload the files
|
||||
goto end
|
||||
)
|
||||
if "a%ftpuser%" == "a" (
|
||||
echo You need to set FTP username in the ftpuser environment variable to upload the files
|
||||
goto end
|
||||
)
|
||||
if "a%ftpsite%" == "a" (
|
||||
echo You need to set FTP server in the ftpsite environment variable to upload the files
|
||||
goto end
|
||||
)
|
||||
ncftpput -p %ftppass% -u %ftpuser% -T temp_ %ftpsite% / Install\MCServer_Win_%WCREV%.7z
|
||||
if errorlevel 1 goto haderror
|
||||
ncftpput -p %ftppass% -u %ftpuser% -T temp_ %ftpsite% /PDBs Install\MCServer_Win_%WCREV%_PDBs.7z
|
||||
if errorlevel 1 goto haderror
|
||||
echo Upload finished.
|
||||
|
||||
|
||||
|
||||
|
||||
goto end
|
||||
|
||||
|
||||
|
||||
|
||||
:haderror
|
||||
echo an error was encountered, check command output above
|
||||
pause
|
||||
goto finished
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:end
|
||||
if "a%1" == "a" pause
|
||||
|
||||
|
||||
|
||||
:finished
|
@ -1,101 +1,101 @@
|
||||
|
||||
// NoiseTest.cpp
|
||||
|
||||
// Implements the main app entrypoint
|
||||
|
||||
#include "Globals.h"
|
||||
#include <time.h>
|
||||
#include "Noise.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void SaveValues(NOISE_DATATYPE * a_Values, const AString & a_FileName)
|
||||
{
|
||||
cFile f;
|
||||
if (!f.Open(a_FileName, cFile::fmWrite))
|
||||
{
|
||||
LOGWARNING("Cannot write file %s", a_FileName.c_str());
|
||||
return;
|
||||
}
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
unsigned char val[256];
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
val[x] = std::min(255, std::max(0, (int)(256 * a_Values[x + 256 * y])));
|
||||
}
|
||||
f.Write(val, 256);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
clock_t TestCubicNoise(void)
|
||||
{
|
||||
cCubicNoise Cubic(0);
|
||||
NOISE_DATATYPE Values[256 * 256];
|
||||
|
||||
// Do a speed test:
|
||||
clock_t Begin = clock();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
Cubic.Generate2D(Values, 256, 256, 0, (NOISE_DATATYPE)25.6, 0, (NOISE_DATATYPE)25.6);
|
||||
}
|
||||
clock_t Ticks = clock() - Begin;
|
||||
LOG("cCubicNoise generating 1000 * 256x256 values took %d ticks (%.02f sec)", Ticks, (double)Ticks / CLOCKS_PER_SEC);
|
||||
|
||||
// Save the results into a file for visual comparison:
|
||||
SaveValues(Values, "NoiseCubic.raw");
|
||||
|
||||
return Ticks;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
clock_t TestOldNoise(void)
|
||||
{
|
||||
cNoise Noise(0);
|
||||
NOISE_DATATYPE Values[256 * 256];
|
||||
|
||||
// Do a speed test:
|
||||
clock_t Begin = clock();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
float fy = (float)y / 10;
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
Values[x + 256 * y] = Noise.CubicNoise2D((float)x / 10, fy);
|
||||
} // for x
|
||||
} // for y
|
||||
}
|
||||
clock_t Ticks = clock() - Begin;
|
||||
LOG("cNoise generating 1000 * 256x256 values took %d ticks (%.02f sec)", Ticks, (double)Ticks / CLOCKS_PER_SEC);
|
||||
|
||||
// Save the results into a file for visual comparison:
|
||||
SaveValues(Values, "NoiseOld.raw");
|
||||
|
||||
return Ticks;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
new cMCLogger(); // Create a logger (will set itself as the main instance
|
||||
|
||||
clock_t NewTicks = TestCubicNoise();
|
||||
clock_t OldTicks = TestOldNoise();
|
||||
LOG("New method is %.02fx faster", (double)OldTicks / NewTicks);
|
||||
LOG("Press Enter to quit program");
|
||||
getchar();
|
||||
}
|
||||
|
||||
// NoiseTest.cpp
|
||||
|
||||
// Implements the main app entrypoint
|
||||
|
||||
#include "Globals.h"
|
||||
#include <time.h>
|
||||
#include "Noise.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void SaveValues(NOISE_DATATYPE * a_Values, const AString & a_FileName)
|
||||
{
|
||||
cFile f;
|
||||
if (!f.Open(a_FileName, cFile::fmWrite))
|
||||
{
|
||||
LOGWARNING("Cannot write file %s", a_FileName.c_str());
|
||||
return;
|
||||
}
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
unsigned char val[256];
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
val[x] = std::min(255, std::max(0, (int)(256 * a_Values[x + 256 * y])));
|
||||
}
|
||||
f.Write(val, 256);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
clock_t TestCubicNoise(void)
|
||||
{
|
||||
cCubicNoise Cubic(0);
|
||||
NOISE_DATATYPE Values[256 * 256];
|
||||
|
||||
// Do a speed test:
|
||||
clock_t Begin = clock();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
Cubic.Generate2D(Values, 256, 256, 0, (NOISE_DATATYPE)25.6, 0, (NOISE_DATATYPE)25.6);
|
||||
}
|
||||
clock_t Ticks = clock() - Begin;
|
||||
LOG("cCubicNoise generating 1000 * 256x256 values took %d ticks (%.02f sec)", Ticks, (double)Ticks / CLOCKS_PER_SEC);
|
||||
|
||||
// Save the results into a file for visual comparison:
|
||||
SaveValues(Values, "NoiseCubic.raw");
|
||||
|
||||
return Ticks;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
clock_t TestOldNoise(void)
|
||||
{
|
||||
cNoise Noise(0);
|
||||
NOISE_DATATYPE Values[256 * 256];
|
||||
|
||||
// Do a speed test:
|
||||
clock_t Begin = clock();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
float fy = (float)y / 10;
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
Values[x + 256 * y] = Noise.CubicNoise2D((float)x / 10, fy);
|
||||
} // for x
|
||||
} // for y
|
||||
}
|
||||
clock_t Ticks = clock() - Begin;
|
||||
LOG("cNoise generating 1000 * 256x256 values took %d ticks (%.02f sec)", Ticks, (double)Ticks / CLOCKS_PER_SEC);
|
||||
|
||||
// Save the results into a file for visual comparison:
|
||||
SaveValues(Values, "NoiseOld.raw");
|
||||
|
||||
return Ticks;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
new cMCLogger(); // Create a logger (will set itself as the main instance
|
||||
|
||||
clock_t NewTicks = TestCubicNoise();
|
||||
clock_t OldTicks = TestOldNoise();
|
||||
LOG("New method is %.02fx faster", (double)OldTicks / NewTicks);
|
||||
LOG("Press Enter to quit program");
|
||||
getchar();
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NoiseTest", "NoiseTest.vcproj", "{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NoiseTest", "NoiseTest.vcproj", "{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
@ -1,258 +1,258 @@
|
||||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="NoiseTest"
|
||||
ProjectGUID="{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}"
|
||||
RootNamespace="NoiseTest"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../source"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="../../source"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\NoiseTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Shared"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\source\Log.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\Log.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\MCLogger.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\MCLogger.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\Noise.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\Noise.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\StringUtils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\StringUtils.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="OSSupport"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\CriticalSection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\CriticalSection.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\File.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\File.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\IsThread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\IsThread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\MakeDir.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\MakeDir.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="NoiseTest"
|
||||
ProjectGUID="{8FDBCFC4-E1CF-4704-999C-29A08F9D6053}"
|
||||
RootNamespace="NoiseTest"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../source"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="../../source"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\NoiseTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Shared"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\source\Log.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\Log.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\MCLogger.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\MCLogger.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\Noise.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\Noise.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\StringUtils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\StringUtils.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="OSSupport"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\CriticalSection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\CriticalSection.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\File.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\File.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\IsThread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\IsThread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\MakeDir.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\MakeDir.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
@ -1,69 +1,69 @@
|
||||
|
||||
// AnvilStats.cpp
|
||||
|
||||
// Implements the main app entrypoint
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Processor.h"
|
||||
#include "Statistics.h"
|
||||
#include "BiomeMap.h"
|
||||
#include "HeightMap.h"
|
||||
#include "ChunkExtract.h"
|
||||
#include "SpringStats.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
LOG("Usage: %s <method number> [<world folder>]", argv[0]);
|
||||
LOG("Available methods:");
|
||||
LOG(" 0 - statistics");
|
||||
LOG(" 1 - biome map");
|
||||
LOG(" 2 - height map");
|
||||
LOG(" 3 - extract chunks");
|
||||
LOG(" 4 - count lava- and water- springs");
|
||||
LOG("\nNo method number present, aborting.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
AString WorldFolder;
|
||||
if (argc > 2)
|
||||
{
|
||||
WorldFolder = argv[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldFolder = "." + cFile::PathSeparator;
|
||||
}
|
||||
|
||||
cCallbackFactory * Factory = NULL;
|
||||
switch (atol(argv[1]))
|
||||
{
|
||||
case 0: Factory = new cStatisticsFactory; break;
|
||||
case 1: Factory = new cBiomeMapFactory; break;
|
||||
case 2: Factory = new cHeightMapFactory; break;
|
||||
case 3: Factory = new cChunkExtractFactory(WorldFolder); break;
|
||||
case 4: Factory = new cSpringStatsFactory; break;
|
||||
default:
|
||||
{
|
||||
LOG("Unknown method \"%s\", aborting.", argv[1]);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
cProcessor Processor;
|
||||
Processor.ProcessWorld(WorldFolder, *Factory);
|
||||
|
||||
LOG("Processing finished");
|
||||
|
||||
delete Factory;
|
||||
|
||||
LOG("Done");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// AnvilStats.cpp
|
||||
|
||||
// Implements the main app entrypoint
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Processor.h"
|
||||
#include "Statistics.h"
|
||||
#include "BiomeMap.h"
|
||||
#include "HeightMap.h"
|
||||
#include "ChunkExtract.h"
|
||||
#include "SpringStats.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
LOG("Usage: %s <method number> [<world folder>]", argv[0]);
|
||||
LOG("Available methods:");
|
||||
LOG(" 0 - statistics");
|
||||
LOG(" 1 - biome map");
|
||||
LOG(" 2 - height map");
|
||||
LOG(" 3 - extract chunks");
|
||||
LOG(" 4 - count lava- and water- springs");
|
||||
LOG("\nNo method number present, aborting.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
AString WorldFolder;
|
||||
if (argc > 2)
|
||||
{
|
||||
WorldFolder = argv[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldFolder = "." + cFile::PathSeparator;
|
||||
}
|
||||
|
||||
cCallbackFactory * Factory = NULL;
|
||||
switch (atol(argv[1]))
|
||||
{
|
||||
case 0: Factory = new cStatisticsFactory; break;
|
||||
case 1: Factory = new cBiomeMapFactory; break;
|
||||
case 2: Factory = new cHeightMapFactory; break;
|
||||
case 3: Factory = new cChunkExtractFactory(WorldFolder); break;
|
||||
case 4: Factory = new cSpringStatsFactory; break;
|
||||
default:
|
||||
{
|
||||
LOG("Unknown method \"%s\", aborting.", argv[1]);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
cProcessor Processor;
|
||||
Processor.ProcessWorld(WorldFolder, *Factory);
|
||||
|
||||
LOG("Processing finished");
|
||||
|
||||
delete Factory;
|
||||
|
||||
LOG("Done");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,34 +1,34 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AnvilStats", "AnvilStats.vcproj", "{CF996A5E-0A86-4004-9710-682B06B5AEBA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA} = {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\VC2008\zlib.vcproj", "{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release profiled|Win32 = Release profiled|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.Build.0 = Release profiled|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.Build.0 = Release|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release profiled|Win32.Build.0 = Release profiled|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AnvilStats", "AnvilStats.vcproj", "{CF996A5E-0A86-4004-9710-682B06B5AEBA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA} = {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\VC2008\zlib.vcproj", "{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release profiled|Win32 = Release profiled|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.Build.0 = Release profiled|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.Build.0 = Release|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release profiled|Win32.Build.0 = Release profiled|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
@ -1,27 +1,27 @@
|
||||
|
||||
// AnvilStats.txt
|
||||
|
||||
// A Readme for the project
|
||||
|
||||
/*
|
||||
AnvilStats
|
||||
==========
|
||||
|
||||
This is a project for measuring various metrics throughout an Anvil world, presumably created by a vanilla MC.
|
||||
It works by parsing the MCA files in the path specified as its param (or current directory, if no params) and
|
||||
feeding each decompressed chunk into the statistics-gathering callback function.
|
||||
|
||||
Possible usage:
|
||||
- count the per-chunk density of specific blocks
|
||||
- count the per-chunk density of dungeons, by measuring the number of zombie/skeleton/regularspider spawners
|
||||
- count the per-chunk-per-biome density of trees, by measuring the number of dirt-log vertical transitions, correlating to biome data
|
||||
|
||||
This project is Windows-only, although it shouldn't be too difficult to make it portable.
|
||||
|
||||
Because this project uses NBT extensively, it runs much faster in Release mode.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
// AnvilStats.txt
|
||||
|
||||
// A Readme for the project
|
||||
|
||||
/*
|
||||
AnvilStats
|
||||
==========
|
||||
|
||||
This is a project for measuring various metrics throughout an Anvil world, presumably created by a vanilla MC.
|
||||
It works by parsing the MCA files in the path specified as its param (or current directory, if no params) and
|
||||
feeding each decompressed chunk into the statistics-gathering callback function.
|
||||
|
||||
Possible usage:
|
||||
- count the per-chunk density of specific blocks
|
||||
- count the per-chunk density of dungeons, by measuring the number of zombie/skeleton/regularspider spawners
|
||||
- count the per-chunk-per-biome density of trees, by measuring the number of dirt-log vertical transitions, correlating to biome data
|
||||
|
||||
This project is Windows-only, although it shouldn't be too difficult to make it portable.
|
||||
|
||||
Because this project uses NBT extensively, it runs much faster in Release mode.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
@ -1,452 +1,452 @@
|
||||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="AnvilStats"
|
||||
ProjectGUID="{CF996A5E-0A86-4004-9710-682B06B5AEBA}"
|
||||
RootNamespace="AnvilStats"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""..\..\zlib-1.2.7""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=""..\..\zlib-1.2.7""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release profiled|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=""..\..\zlib-1.2.7""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
Profile="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AnvilStats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeMap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Callback.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChunkExtract.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChunkExtract.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Globals.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release profiled|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Globals.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightMap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Processor.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Processor.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpringStats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpringStats.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Statistics.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Statistics.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="shared"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\CriticalSection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\CriticalSection.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\Endianness.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\Event.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\Event.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\WorldStorage\FastNBT.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release profiled|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\WorldStorage\FastNBT.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\File.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\File.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\GZipFile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\GZipFile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\IsThread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\IsThread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\StringUtils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\StringUtils.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\AnvilStats.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="AnvilStats"
|
||||
ProjectGUID="{CF996A5E-0A86-4004-9710-682B06B5AEBA}"
|
||||
RootNamespace="AnvilStats"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""..\..\zlib-1.2.7""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=""..\..\zlib-1.2.7""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release profiled|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=""..\..\zlib-1.2.7""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
Profile="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AnvilStats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeMap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Callback.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChunkExtract.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChunkExtract.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Globals.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release profiled|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Globals.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightMap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Processor.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Processor.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpringStats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpringStats.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Statistics.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Statistics.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="shared"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\CriticalSection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\CriticalSection.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\Endianness.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\Event.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\Event.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\WorldStorage\FastNBT.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release profiled|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\WorldStorage\FastNBT.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\File.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\File.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\GZipFile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\GZipFile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\IsThread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\OSSupport\IsThread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\StringUtils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\source\StringUtils.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\AnvilStats.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
@ -1,172 +1,172 @@
|
||||
|
||||
// BiomeMap.cpp
|
||||
|
||||
// Implements the cBiomeMap class representing a cCallback descendant that draws a map of biomes for the world
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeMap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const int g_BiomePalette[] =
|
||||
{
|
||||
// ARGB:
|
||||
0xff0000ff, /* Ocean */
|
||||
0xff00cf3f, /* Plains */
|
||||
0xffffff00, /* Desert */
|
||||
0xff7f7f7f, /* Extreme Hills */
|
||||
0xff00cf00, /* Forest */
|
||||
0xff007f3f, /* Taiga */
|
||||
0xff3f7f00, /* Swampland */
|
||||
0xff003fff, /* River */
|
||||
0xff7f0000, /* Hell */
|
||||
0xff007fff, /* Sky */
|
||||
0xff3f3fff, /* Frozen Ocean */
|
||||
0xff3f3fff, /* Frozen River */
|
||||
0xff7fffcf, /* Ice Plains */
|
||||
0xff3fcf7f, /* Ice Mountains */
|
||||
0xffcf00cf, /* Mushroom Island */
|
||||
0xff7f00ff, /* Mushroom Island Shore */
|
||||
0xffffff3f, /* Beach */
|
||||
0xffcfcf00, /* Desert Hills */
|
||||
0xff00cf3f, /* Forest Hills */
|
||||
0xff006f1f, /* Taiga Hills */
|
||||
0xff7f8f7f, /* Extreme Hills Edge */
|
||||
0xff004f00, /* Jungle */
|
||||
0xff003f00, /* Jungle Hills */
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const unsigned char g_BMPHeader[] =
|
||||
{
|
||||
0x42, 0x4D, 0x36, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeMap::cBiomeMap(void) :
|
||||
m_CurrentRegionX(0),
|
||||
m_CurrentRegionZ(0),
|
||||
m_IsCurrentRegionValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeMap::Finish(void)
|
||||
{
|
||||
if (m_IsCurrentRegionValid)
|
||||
{
|
||||
StartNewRegion(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeMap::OnNewChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
int RegionX = (a_ChunkX < 0) ? (a_ChunkX - 31) / 32 : a_ChunkX / 32;
|
||||
int RegionZ = (a_ChunkZ < 0) ? (a_ChunkZ - 31) / 32 : a_ChunkZ / 32;
|
||||
if ((RegionX != m_CurrentRegionX) || (RegionZ != m_CurrentRegionZ))
|
||||
{
|
||||
if (m_IsCurrentRegionValid)
|
||||
{
|
||||
StartNewRegion(RegionX, RegionZ);
|
||||
}
|
||||
m_CurrentRegionX = RegionX;
|
||||
m_CurrentRegionZ = RegionZ;
|
||||
}
|
||||
m_IsCurrentRegionValid = true;
|
||||
m_CurrentChunkX = a_ChunkX;
|
||||
m_CurrentChunkZ = a_ChunkZ;
|
||||
m_CurrentChunkOffX = m_CurrentChunkX - m_CurrentRegionX * 32;
|
||||
m_CurrentChunkOffZ = m_CurrentChunkZ - m_CurrentRegionZ * 32;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeMap::OnBiomes(const unsigned char * a_BiomeData)
|
||||
{
|
||||
ASSERT(m_CurrentChunkOffX >= 0);
|
||||
ASSERT(m_CurrentChunkOffX < 32);
|
||||
ASSERT(m_CurrentChunkOffZ >= 0);
|
||||
ASSERT(m_CurrentChunkOffZ < 32);
|
||||
char * BaseBiomes = m_Biomes + m_CurrentChunkOffZ * 16 * 512 + m_CurrentChunkOffX * 16;
|
||||
for (int z = 0; z < 16; z++)
|
||||
{
|
||||
char * Row = BaseBiomes + z * 512;
|
||||
memcpy(Row, a_BiomeData + z * 16, 16);
|
||||
} // for z
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeMap::StartNewRegion(int a_RegionX, int a_RegionZ)
|
||||
{
|
||||
AString FileName;
|
||||
Printf(FileName, "Biomes.%d.%d.bmp", m_CurrentRegionX, m_CurrentRegionZ);
|
||||
cFile f;
|
||||
if (!f.Open(FileName, cFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot open file \"%s\" for writing the biome map. Data for this region lost.", FileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
f.Write(g_BMPHeader, sizeof(g_BMPHeader));
|
||||
for (int z = 0; z < 512; z++)
|
||||
{
|
||||
int RowData[512];
|
||||
unsigned char * BiomeRow = (unsigned char *)m_Biomes + z * 512;
|
||||
for (int x = 0; x < 512; x++)
|
||||
{
|
||||
RowData[x] = g_BiomePalette[BiomeRow[x]];
|
||||
}
|
||||
f.Write(RowData, sizeof(RowData));
|
||||
} // for z
|
||||
}
|
||||
|
||||
memset(m_Biomes, 0, sizeof(m_Biomes));
|
||||
m_CurrentRegionX = a_RegionX;
|
||||
m_CurrentRegionZ = a_RegionZ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeMapFactory:
|
||||
|
||||
cBiomeMapFactory::~cBiomeMapFactory()
|
||||
{
|
||||
// Force all threads to save their last regions:
|
||||
for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr)
|
||||
{
|
||||
((cBiomeMap *)(*itr))->Finish();
|
||||
}
|
||||
// TODO: Join all the files into one giant image file
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// BiomeMap.cpp
|
||||
|
||||
// Implements the cBiomeMap class representing a cCallback descendant that draws a map of biomes for the world
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeMap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const int g_BiomePalette[] =
|
||||
{
|
||||
// ARGB:
|
||||
0xff0000ff, /* Ocean */
|
||||
0xff00cf3f, /* Plains */
|
||||
0xffffff00, /* Desert */
|
||||
0xff7f7f7f, /* Extreme Hills */
|
||||
0xff00cf00, /* Forest */
|
||||
0xff007f3f, /* Taiga */
|
||||
0xff3f7f00, /* Swampland */
|
||||
0xff003fff, /* River */
|
||||
0xff7f0000, /* Hell */
|
||||
0xff007fff, /* Sky */
|
||||
0xff3f3fff, /* Frozen Ocean */
|
||||
0xff3f3fff, /* Frozen River */
|
||||
0xff7fffcf, /* Ice Plains */
|
||||
0xff3fcf7f, /* Ice Mountains */
|
||||
0xffcf00cf, /* Mushroom Island */
|
||||
0xff7f00ff, /* Mushroom Island Shore */
|
||||
0xffffff3f, /* Beach */
|
||||
0xffcfcf00, /* Desert Hills */
|
||||
0xff00cf3f, /* Forest Hills */
|
||||
0xff006f1f, /* Taiga Hills */
|
||||
0xff7f8f7f, /* Extreme Hills Edge */
|
||||
0xff004f00, /* Jungle */
|
||||
0xff003f00, /* Jungle Hills */
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const unsigned char g_BMPHeader[] =
|
||||
{
|
||||
0x42, 0x4D, 0x36, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeMap::cBiomeMap(void) :
|
||||
m_CurrentRegionX(0),
|
||||
m_CurrentRegionZ(0),
|
||||
m_IsCurrentRegionValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeMap::Finish(void)
|
||||
{
|
||||
if (m_IsCurrentRegionValid)
|
||||
{
|
||||
StartNewRegion(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeMap::OnNewChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
int RegionX = (a_ChunkX < 0) ? (a_ChunkX - 31) / 32 : a_ChunkX / 32;
|
||||
int RegionZ = (a_ChunkZ < 0) ? (a_ChunkZ - 31) / 32 : a_ChunkZ / 32;
|
||||
if ((RegionX != m_CurrentRegionX) || (RegionZ != m_CurrentRegionZ))
|
||||
{
|
||||
if (m_IsCurrentRegionValid)
|
||||
{
|
||||
StartNewRegion(RegionX, RegionZ);
|
||||
}
|
||||
m_CurrentRegionX = RegionX;
|
||||
m_CurrentRegionZ = RegionZ;
|
||||
}
|
||||
m_IsCurrentRegionValid = true;
|
||||
m_CurrentChunkX = a_ChunkX;
|
||||
m_CurrentChunkZ = a_ChunkZ;
|
||||
m_CurrentChunkOffX = m_CurrentChunkX - m_CurrentRegionX * 32;
|
||||
m_CurrentChunkOffZ = m_CurrentChunkZ - m_CurrentRegionZ * 32;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeMap::OnBiomes(const unsigned char * a_BiomeData)
|
||||
{
|
||||
ASSERT(m_CurrentChunkOffX >= 0);
|
||||
ASSERT(m_CurrentChunkOffX < 32);
|
||||
ASSERT(m_CurrentChunkOffZ >= 0);
|
||||
ASSERT(m_CurrentChunkOffZ < 32);
|
||||
char * BaseBiomes = m_Biomes + m_CurrentChunkOffZ * 16 * 512 + m_CurrentChunkOffX * 16;
|
||||
for (int z = 0; z < 16; z++)
|
||||
{
|
||||
char * Row = BaseBiomes + z * 512;
|
||||
memcpy(Row, a_BiomeData + z * 16, 16);
|
||||
} // for z
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeMap::StartNewRegion(int a_RegionX, int a_RegionZ)
|
||||
{
|
||||
AString FileName;
|
||||
Printf(FileName, "Biomes.%d.%d.bmp", m_CurrentRegionX, m_CurrentRegionZ);
|
||||
cFile f;
|
||||
if (!f.Open(FileName, cFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot open file \"%s\" for writing the biome map. Data for this region lost.", FileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
f.Write(g_BMPHeader, sizeof(g_BMPHeader));
|
||||
for (int z = 0; z < 512; z++)
|
||||
{
|
||||
int RowData[512];
|
||||
unsigned char * BiomeRow = (unsigned char *)m_Biomes + z * 512;
|
||||
for (int x = 0; x < 512; x++)
|
||||
{
|
||||
RowData[x] = g_BiomePalette[BiomeRow[x]];
|
||||
}
|
||||
f.Write(RowData, sizeof(RowData));
|
||||
} // for z
|
||||
}
|
||||
|
||||
memset(m_Biomes, 0, sizeof(m_Biomes));
|
||||
m_CurrentRegionX = a_RegionX;
|
||||
m_CurrentRegionZ = a_RegionZ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeMapFactory:
|
||||
|
||||
cBiomeMapFactory::~cBiomeMapFactory()
|
||||
{
|
||||
// Force all threads to save their last regions:
|
||||
for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr)
|
||||
{
|
||||
((cBiomeMap *)(*itr))->Finish();
|
||||
}
|
||||
// TODO: Join all the files into one giant image file
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,69 +1,69 @@
|
||||
|
||||
// BiomeMap.h
|
||||
|
||||
// Interfaces to the cBiomeMap class representing a cCallback descendant that draws a map of biomes for the world
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callback.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeMap :
|
||||
public cCallback
|
||||
{
|
||||
public:
|
||||
cBiomeMap(void);
|
||||
|
||||
/// Saves the last region that it was processing
|
||||
void Finish(void);
|
||||
|
||||
protected:
|
||||
int m_CurrentChunkX; // Absolute chunk coords
|
||||
int m_CurrentChunkZ;
|
||||
int m_CurrentChunkOffX; // Chunk offset from the start of the region
|
||||
int m_CurrentChunkOffZ;
|
||||
int m_CurrentRegionX;
|
||||
int m_CurrentRegionZ;
|
||||
bool m_IsCurrentRegionValid;
|
||||
char m_Biomes[16 * 32 * 16 * 32]; // Biome map of the entire current region [x + 16 * 32 * z]
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) override { return false; }
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override { return false; }
|
||||
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) override { return false; }
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) override { return false; }
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) override { return !a_Populated; } // If not populated, we don't want it!
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) override;
|
||||
|
||||
void StartNewRegion(int a_RegionX, int a_RegionZ);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeMapFactory :
|
||||
public cCallbackFactory
|
||||
{
|
||||
public:
|
||||
virtual ~cBiomeMapFactory();
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cBiomeMap;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// BiomeMap.h
|
||||
|
||||
// Interfaces to the cBiomeMap class representing a cCallback descendant that draws a map of biomes for the world
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callback.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeMap :
|
||||
public cCallback
|
||||
{
|
||||
public:
|
||||
cBiomeMap(void);
|
||||
|
||||
/// Saves the last region that it was processing
|
||||
void Finish(void);
|
||||
|
||||
protected:
|
||||
int m_CurrentChunkX; // Absolute chunk coords
|
||||
int m_CurrentChunkZ;
|
||||
int m_CurrentChunkOffX; // Chunk offset from the start of the region
|
||||
int m_CurrentChunkOffZ;
|
||||
int m_CurrentRegionX;
|
||||
int m_CurrentRegionZ;
|
||||
bool m_IsCurrentRegionValid;
|
||||
char m_Biomes[16 * 32 * 16 * 32]; // Biome map of the entire current region [x + 16 * 32 * z]
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) override { return false; }
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override { return false; }
|
||||
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) override { return false; }
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) override { return false; }
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) override { return !a_Populated; } // If not populated, we don't want it!
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) override;
|
||||
|
||||
void StartNewRegion(int a_RegionX, int a_RegionZ);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeMapFactory :
|
||||
public cCallbackFactory
|
||||
{
|
||||
public:
|
||||
virtual ~cBiomeMapFactory();
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cBiomeMap;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,165 +1,165 @@
|
||||
|
||||
// Callback.h
|
||||
|
||||
// Interfaces to the cCallback base class used as the base class for all statistical callbacks
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cParsedNBT;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** The base class for all chunk-processor callbacks, declares the interface.
|
||||
The processor calls each virtual function in the order they are declared here with the specified args.
|
||||
If the function returns true, the processor moves on to next chunk and starts calling the callbacks again from start with
|
||||
the new chunk data.
|
||||
So if a statistics collector doesn't need data decompression at all, it can stop the processor from doing so early-enough
|
||||
and still get meaningful data.
|
||||
A callback is guaranteed to run in a single thread and always the same thread.
|
||||
A callback is guaranteed to run on all chunks in a region and one region is guaranteed to be handled by only callback.
|
||||
*/
|
||||
class cCallback abstract
|
||||
{
|
||||
public:
|
||||
virtual ~cCallback() {} // Force a virtual destructor in each descendant
|
||||
|
||||
/// Called to inform the stats module of the chunk coords for newly processing chunk
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) = 0;
|
||||
|
||||
/// Called to inform about the chunk's data offset in the file (chunk mini-header), the number of sectors it uses and the timestamp field value
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) { return true; }
|
||||
|
||||
/// Called to inform of the compressed chunk data size and position in the file (offset from file start to the actual data)
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) { return true; }
|
||||
|
||||
/// Just in case you wanted to process the NBT yourself ;)
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) { return true; }
|
||||
|
||||
/// The chunk's NBT should specify chunk coords, these are sent here:
|
||||
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) { return true; }
|
||||
|
||||
/// The chunk contains a LastUpdate value specifying the last tick in which it was saved.
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) { return true; }
|
||||
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) { return true; }
|
||||
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) { return true; }
|
||||
|
||||
/** Called when a heightmap for the chunk is read from the file.
|
||||
Note that the heightmap is given in big-endian ints, so if you want it, you need to ntohl() it first!
|
||||
*/
|
||||
virtual bool OnHeightMap(const int * a_HeightMapBE) { return true; }
|
||||
|
||||
/** If there is data for the section, this callback is called; otherwise OnEmptySection() is called instead.
|
||||
All OnSection() callbacks are called first, and only then all the remaining sections are reported in OnEmptySection().
|
||||
*/
|
||||
virtual bool OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
) { return true; }
|
||||
|
||||
/** If there is no data for a section, this callback is called; otherwise OnSection() is called instead.
|
||||
OnEmptySection() callbacks are called after all OnSection() callbacks.
|
||||
*/
|
||||
virtual bool OnEmptySection(unsigned char a_Y) { return false; }
|
||||
|
||||
/** Called after all sections have been processed via either OnSection() or OnEmptySection().
|
||||
*/
|
||||
virtual bool OnSectionsFinished(void) { return true; }
|
||||
|
||||
/** Called for each entity in the chunk.
|
||||
Common parameters are parsed from the NBT.
|
||||
The callback may parse any other param from the a_NBT and a_NBTTag parameters.
|
||||
The a_NBTTag parameter points to the entity compound tag inside the Entities tag.
|
||||
*/
|
||||
virtual bool OnEntity(
|
||||
const AString & a_EntityType,
|
||||
double a_PosX, double a_PosY, double a_PosZ,
|
||||
double a_SpeedX, double a_SpeedY, double a_SpeedZ,
|
||||
float a_Yaw, float a_Pitch,
|
||||
float a_FallDistance,
|
||||
short a_FireTicksLeft,
|
||||
short a_AirTicks,
|
||||
char a_IsOnGround,
|
||||
cParsedNBT & a_NBT,
|
||||
int a_NBTTag
|
||||
) { return true; }
|
||||
|
||||
/** Called for each tile entity in the chunk.
|
||||
Common parameters are parsed from the NBT.
|
||||
The callback may parse any other param from the a_NBT and a_NBTTag parameters.
|
||||
The a_NBTTag parameter points to the tile entity compound tag inside the TileEntities tag.
|
||||
*/
|
||||
virtual bool OnTileEntity(
|
||||
const AString & a_EntityType,
|
||||
int a_PosX, int a_PosY, int a_PosZ,
|
||||
cParsedNBT & a_NBT,
|
||||
int a_NBTTag
|
||||
) { return true; }
|
||||
|
||||
/// Called for each tile tick in the chunk
|
||||
virtual bool OnTileTick(
|
||||
int a_BlockType,
|
||||
int a_TicksLeft,
|
||||
int a_PosX, int a_PosY, int a_PosZ
|
||||
) { return true; }
|
||||
} ;
|
||||
|
||||
typedef std::vector<cCallback *> cCallbacks;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** The base class for a factory that creates callback objects for separate threads.
|
||||
The processor creates a callback for each thread on which it runs using this factory.
|
||||
The factory is guaranteed to be called from a single thread.
|
||||
The factory keeps track of all the callbacks that it has created and deletes them when destructed
|
||||
*/
|
||||
class cCallbackFactory
|
||||
{
|
||||
public:
|
||||
virtual ~cCallbackFactory()
|
||||
{
|
||||
for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr)
|
||||
{
|
||||
delete *itr;
|
||||
}
|
||||
}
|
||||
|
||||
/// Descendants override this method to return the correct callback type
|
||||
virtual cCallback * CreateNewCallback(void) = 0;
|
||||
|
||||
/// cProcessor uses this method to request a new callback
|
||||
cCallback * GetNewCallback(void)
|
||||
{
|
||||
cCallback * Callback = CreateNewCallback();
|
||||
if (Callback != NULL)
|
||||
{
|
||||
m_Callbacks.push_back(Callback);
|
||||
}
|
||||
return Callback;
|
||||
}
|
||||
|
||||
protected:
|
||||
cCallbacks m_Callbacks;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Callback.h
|
||||
|
||||
// Interfaces to the cCallback base class used as the base class for all statistical callbacks
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cParsedNBT;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** The base class for all chunk-processor callbacks, declares the interface.
|
||||
The processor calls each virtual function in the order they are declared here with the specified args.
|
||||
If the function returns true, the processor moves on to next chunk and starts calling the callbacks again from start with
|
||||
the new chunk data.
|
||||
So if a statistics collector doesn't need data decompression at all, it can stop the processor from doing so early-enough
|
||||
and still get meaningful data.
|
||||
A callback is guaranteed to run in a single thread and always the same thread.
|
||||
A callback is guaranteed to run on all chunks in a region and one region is guaranteed to be handled by only callback.
|
||||
*/
|
||||
class cCallback abstract
|
||||
{
|
||||
public:
|
||||
virtual ~cCallback() {} // Force a virtual destructor in each descendant
|
||||
|
||||
/// Called to inform the stats module of the chunk coords for newly processing chunk
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) = 0;
|
||||
|
||||
/// Called to inform about the chunk's data offset in the file (chunk mini-header), the number of sectors it uses and the timestamp field value
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) { return true; }
|
||||
|
||||
/// Called to inform of the compressed chunk data size and position in the file (offset from file start to the actual data)
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) { return true; }
|
||||
|
||||
/// Just in case you wanted to process the NBT yourself ;)
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) { return true; }
|
||||
|
||||
/// The chunk's NBT should specify chunk coords, these are sent here:
|
||||
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) { return true; }
|
||||
|
||||
/// The chunk contains a LastUpdate value specifying the last tick in which it was saved.
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) { return true; }
|
||||
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) { return true; }
|
||||
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) { return true; }
|
||||
|
||||
/** Called when a heightmap for the chunk is read from the file.
|
||||
Note that the heightmap is given in big-endian ints, so if you want it, you need to ntohl() it first!
|
||||
*/
|
||||
virtual bool OnHeightMap(const int * a_HeightMapBE) { return true; }
|
||||
|
||||
/** If there is data for the section, this callback is called; otherwise OnEmptySection() is called instead.
|
||||
All OnSection() callbacks are called first, and only then all the remaining sections are reported in OnEmptySection().
|
||||
*/
|
||||
virtual bool OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
) { return true; }
|
||||
|
||||
/** If there is no data for a section, this callback is called; otherwise OnSection() is called instead.
|
||||
OnEmptySection() callbacks are called after all OnSection() callbacks.
|
||||
*/
|
||||
virtual bool OnEmptySection(unsigned char a_Y) { return false; }
|
||||
|
||||
/** Called after all sections have been processed via either OnSection() or OnEmptySection().
|
||||
*/
|
||||
virtual bool OnSectionsFinished(void) { return true; }
|
||||
|
||||
/** Called for each entity in the chunk.
|
||||
Common parameters are parsed from the NBT.
|
||||
The callback may parse any other param from the a_NBT and a_NBTTag parameters.
|
||||
The a_NBTTag parameter points to the entity compound tag inside the Entities tag.
|
||||
*/
|
||||
virtual bool OnEntity(
|
||||
const AString & a_EntityType,
|
||||
double a_PosX, double a_PosY, double a_PosZ,
|
||||
double a_SpeedX, double a_SpeedY, double a_SpeedZ,
|
||||
float a_Yaw, float a_Pitch,
|
||||
float a_FallDistance,
|
||||
short a_FireTicksLeft,
|
||||
short a_AirTicks,
|
||||
char a_IsOnGround,
|
||||
cParsedNBT & a_NBT,
|
||||
int a_NBTTag
|
||||
) { return true; }
|
||||
|
||||
/** Called for each tile entity in the chunk.
|
||||
Common parameters are parsed from the NBT.
|
||||
The callback may parse any other param from the a_NBT and a_NBTTag parameters.
|
||||
The a_NBTTag parameter points to the tile entity compound tag inside the TileEntities tag.
|
||||
*/
|
||||
virtual bool OnTileEntity(
|
||||
const AString & a_EntityType,
|
||||
int a_PosX, int a_PosY, int a_PosZ,
|
||||
cParsedNBT & a_NBT,
|
||||
int a_NBTTag
|
||||
) { return true; }
|
||||
|
||||
/// Called for each tile tick in the chunk
|
||||
virtual bool OnTileTick(
|
||||
int a_BlockType,
|
||||
int a_TicksLeft,
|
||||
int a_PosX, int a_PosY, int a_PosZ
|
||||
) { return true; }
|
||||
} ;
|
||||
|
||||
typedef std::vector<cCallback *> cCallbacks;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** The base class for a factory that creates callback objects for separate threads.
|
||||
The processor creates a callback for each thread on which it runs using this factory.
|
||||
The factory is guaranteed to be called from a single thread.
|
||||
The factory keeps track of all the callbacks that it has created and deletes them when destructed
|
||||
*/
|
||||
class cCallbackFactory
|
||||
{
|
||||
public:
|
||||
virtual ~cCallbackFactory()
|
||||
{
|
||||
for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr)
|
||||
{
|
||||
delete *itr;
|
||||
}
|
||||
}
|
||||
|
||||
/// Descendants override this method to return the correct callback type
|
||||
virtual cCallback * CreateNewCallback(void) = 0;
|
||||
|
||||
/// cProcessor uses this method to request a new callback
|
||||
cCallback * GetNewCallback(void)
|
||||
{
|
||||
cCallback * Callback = CreateNewCallback();
|
||||
if (Callback != NULL)
|
||||
{
|
||||
m_Callbacks.push_back(Callback);
|
||||
}
|
||||
return Callback;
|
||||
}
|
||||
|
||||
protected:
|
||||
cCallbacks m_Callbacks;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,104 +1,104 @@
|
||||
|
||||
// ChunkExtract.cpp
|
||||
|
||||
// Implements the cChunkExtract class representing a cCallback descendant that extracts raw chunk data into separate .chunk files
|
||||
|
||||
#include "Globals.h"
|
||||
#include "ChunkExtract.h"
|
||||
#include "../../source/OSSupport/GZipFile.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cChunkExtract::cChunkExtract(const AString & iWorldFolder) :
|
||||
mWorldFolder(iWorldFolder)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkExtract::OnNewChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
int AnvilX = (a_ChunkX - ((a_ChunkX > 0) ? 0 : 31)) / 32;
|
||||
int AnvilZ = (a_ChunkZ - ((a_ChunkZ > 0) ? 0 : 31)) / 32;
|
||||
if ((AnvilX != mCurAnvilX) || (AnvilZ != mCurAnvilZ))
|
||||
{
|
||||
OpenAnvilFile(AnvilX, AnvilZ);
|
||||
}
|
||||
mCurChunkX = a_ChunkX;
|
||||
mCurChunkZ = a_ChunkZ;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkExtract::OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod)
|
||||
{
|
||||
if (!mAnvilFile.IsOpen())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
cFile ChunkFile;
|
||||
AString ChunkPath = Printf("%d.%d.zchunk", mCurChunkX, mCurChunkZ);
|
||||
if (!ChunkFile.Open(ChunkPath, cFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot open zchunk file \"%s\" for writing. Chunk [%d, %d] skipped.", ChunkPath.c_str(), mCurChunkX, mCurChunkZ);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy data from mAnvilFile to ChunkFile:
|
||||
mAnvilFile.Seek(a_DataOffset);
|
||||
for (int BytesToCopy = a_CompressedDataSize; BytesToCopy > 0; )
|
||||
{
|
||||
char Buffer[64000];
|
||||
int NumBytes = std::min(BytesToCopy, (int)sizeof(Buffer));
|
||||
int BytesRead = mAnvilFile.Read(Buffer, NumBytes);
|
||||
if (BytesRead != NumBytes)
|
||||
{
|
||||
LOG("Cannot copy chunk data, chunk [%d, %d] is probably corrupted. Skipping chunk.", mCurChunkX, mCurChunkZ);
|
||||
return false;
|
||||
}
|
||||
ChunkFile.Write(Buffer, BytesRead);
|
||||
BytesToCopy -= BytesRead;
|
||||
} // for BytesToCopy
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkExtract::OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize)
|
||||
{
|
||||
ASSERT(mAnvilFile.IsOpen()); // If it weren't, the OnCompressedDataSizePos would've prevented this from running
|
||||
AString FileName = Printf("%d.%d.gzchunk", mCurChunkX, mCurChunkZ);
|
||||
cGZipFile GZipChunk;
|
||||
if (!GZipChunk.Open(FileName, cGZipFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot open gzchunk file \"%s\" for writing. Chunk [%d, %d] skipped.", FileName.c_str(), mCurChunkX, mCurChunkZ);
|
||||
return true;
|
||||
}
|
||||
GZipChunk.Write(a_DecompressedNBT, a_DataSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkExtract::OpenAnvilFile(int a_AnvilX, int a_AnvilZ)
|
||||
{
|
||||
mAnvilFile.Close();
|
||||
AString FileName = Printf("%s/r.%d.%d.mca", mWorldFolder.c_str(), a_AnvilX, a_AnvilZ);
|
||||
if (!mAnvilFile.Open(FileName, cFile::fmRead))
|
||||
{
|
||||
LOG("Cannot open Anvil file \"%s\" for reading", FileName.c_str());
|
||||
}
|
||||
mCurAnvilX = a_AnvilX;
|
||||
mCurAnvilZ = a_AnvilZ;
|
||||
|
||||
// ChunkExtract.cpp
|
||||
|
||||
// Implements the cChunkExtract class representing a cCallback descendant that extracts raw chunk data into separate .chunk files
|
||||
|
||||
#include "Globals.h"
|
||||
#include "ChunkExtract.h"
|
||||
#include "../../source/OSSupport/GZipFile.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cChunkExtract::cChunkExtract(const AString & iWorldFolder) :
|
||||
mWorldFolder(iWorldFolder)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkExtract::OnNewChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
int AnvilX = (a_ChunkX - ((a_ChunkX > 0) ? 0 : 31)) / 32;
|
||||
int AnvilZ = (a_ChunkZ - ((a_ChunkZ > 0) ? 0 : 31)) / 32;
|
||||
if ((AnvilX != mCurAnvilX) || (AnvilZ != mCurAnvilZ))
|
||||
{
|
||||
OpenAnvilFile(AnvilX, AnvilZ);
|
||||
}
|
||||
mCurChunkX = a_ChunkX;
|
||||
mCurChunkZ = a_ChunkZ;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkExtract::OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod)
|
||||
{
|
||||
if (!mAnvilFile.IsOpen())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
cFile ChunkFile;
|
||||
AString ChunkPath = Printf("%d.%d.zchunk", mCurChunkX, mCurChunkZ);
|
||||
if (!ChunkFile.Open(ChunkPath, cFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot open zchunk file \"%s\" for writing. Chunk [%d, %d] skipped.", ChunkPath.c_str(), mCurChunkX, mCurChunkZ);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy data from mAnvilFile to ChunkFile:
|
||||
mAnvilFile.Seek(a_DataOffset);
|
||||
for (int BytesToCopy = a_CompressedDataSize; BytesToCopy > 0; )
|
||||
{
|
||||
char Buffer[64000];
|
||||
int NumBytes = std::min(BytesToCopy, (int)sizeof(Buffer));
|
||||
int BytesRead = mAnvilFile.Read(Buffer, NumBytes);
|
||||
if (BytesRead != NumBytes)
|
||||
{
|
||||
LOG("Cannot copy chunk data, chunk [%d, %d] is probably corrupted. Skipping chunk.", mCurChunkX, mCurChunkZ);
|
||||
return false;
|
||||
}
|
||||
ChunkFile.Write(Buffer, BytesRead);
|
||||
BytesToCopy -= BytesRead;
|
||||
} // for BytesToCopy
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkExtract::OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize)
|
||||
{
|
||||
ASSERT(mAnvilFile.IsOpen()); // If it weren't, the OnCompressedDataSizePos would've prevented this from running
|
||||
AString FileName = Printf("%d.%d.gzchunk", mCurChunkX, mCurChunkZ);
|
||||
cGZipFile GZipChunk;
|
||||
if (!GZipChunk.Open(FileName, cGZipFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot open gzchunk file \"%s\" for writing. Chunk [%d, %d] skipped.", FileName.c_str(), mCurChunkX, mCurChunkZ);
|
||||
return true;
|
||||
}
|
||||
GZipChunk.Write(a_DecompressedNBT, a_DataSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkExtract::OpenAnvilFile(int a_AnvilX, int a_AnvilZ)
|
||||
{
|
||||
mAnvilFile.Close();
|
||||
AString FileName = Printf("%s/r.%d.%d.mca", mWorldFolder.c_str(), a_AnvilX, a_AnvilZ);
|
||||
if (!mAnvilFile.Open(FileName, cFile::fmRead))
|
||||
{
|
||||
LOG("Cannot open Anvil file \"%s\" for reading", FileName.c_str());
|
||||
}
|
||||
mCurAnvilX = a_AnvilX;
|
||||
mCurAnvilZ = a_AnvilZ;
|
||||
}
|
@ -1,66 +1,66 @@
|
||||
|
||||
// ChunkExtract.h
|
||||
|
||||
// Declares the cChunkExtract class representing a cCallback descendant that extracts raw chunk data into separate .chunk files
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callback.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cChunkExtract :
|
||||
public cCallback
|
||||
{
|
||||
public:
|
||||
cChunkExtract(const AString & iWorldFolder);
|
||||
|
||||
protected:
|
||||
AString mWorldFolder;
|
||||
cFile mAnvilFile;
|
||||
int mCurAnvilX; // X-coord of mAnvilFile, in Anvil-coords (1 Anvil-coord = 32 chunks)
|
||||
int mCurAnvilZ; // Z-coord of mAnvilFile, -"-
|
||||
int mCurChunkX; // X-coord of the chunk being processed
|
||||
int mCurChunkZ; // Z-coord of the chunk being processed
|
||||
|
||||
/// Opens new anvil file into mAnvilFile, sets mCurAnvilX and mCurAnvilZ
|
||||
void OpenAnvilFile(int a_AnvilX, int a_AnvilZ);
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) override;
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cChunkExtractFactory :
|
||||
public cCallbackFactory
|
||||
{
|
||||
public:
|
||||
cChunkExtractFactory(const AString & iWorldFolder) :
|
||||
mWorldFolder(iWorldFolder)
|
||||
{
|
||||
}
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cChunkExtract(mWorldFolder);
|
||||
}
|
||||
|
||||
protected:
|
||||
AString mWorldFolder;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ChunkExtract.h
|
||||
|
||||
// Declares the cChunkExtract class representing a cCallback descendant that extracts raw chunk data into separate .chunk files
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callback.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cChunkExtract :
|
||||
public cCallback
|
||||
{
|
||||
public:
|
||||
cChunkExtract(const AString & iWorldFolder);
|
||||
|
||||
protected:
|
||||
AString mWorldFolder;
|
||||
cFile mAnvilFile;
|
||||
int mCurAnvilX; // X-coord of mAnvilFile, in Anvil-coords (1 Anvil-coord = 32 chunks)
|
||||
int mCurAnvilZ; // Z-coord of mAnvilFile, -"-
|
||||
int mCurChunkX; // X-coord of the chunk being processed
|
||||
int mCurChunkZ; // Z-coord of the chunk being processed
|
||||
|
||||
/// Opens new anvil file into mAnvilFile, sets mCurAnvilX and mCurAnvilZ
|
||||
void OpenAnvilFile(int a_AnvilX, int a_AnvilZ);
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) override;
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cChunkExtractFactory :
|
||||
public cCallbackFactory
|
||||
{
|
||||
public:
|
||||
cChunkExtractFactory(const AString & iWorldFolder) :
|
||||
mWorldFolder(iWorldFolder)
|
||||
{
|
||||
}
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cChunkExtract(mWorldFolder);
|
||||
}
|
||||
|
||||
protected:
|
||||
AString mWorldFolder;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
|
||||
// Globals.cpp
|
||||
|
||||
// This file is used for precompiled header generation in MSVC environments
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Globals.cpp
|
||||
|
||||
// This file is used for precompiled header generation in MSVC environments
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,228 +1,228 @@
|
||||
|
||||
// Globals.h
|
||||
|
||||
// This file gets included from every module in the project, so that global symbols may be introduced easily
|
||||
// Also used for precompiled header generation in MSVC environments
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Compiler-dependent stuff:
|
||||
#if defined(_MSC_VER)
|
||||
// MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether
|
||||
#pragma warning(disable:4481)
|
||||
|
||||
// Disable some warnings that we don't care about:
|
||||
#pragma warning(disable:4100)
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#define OBSOLETE __declspec(deprecated)
|
||||
|
||||
// No alignment needed in MSVC
|
||||
#define ALIGN_8
|
||||
#define ALIGN_16
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
// TODO: Can GCC explicitly mark classes as abstract (no instances can be created)?
|
||||
#define abstract
|
||||
|
||||
// TODO: Can GCC mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class)
|
||||
#define override
|
||||
|
||||
#define OBSOLETE __attribute__((deprecated))
|
||||
|
||||
#define ALIGN_8 __attribute__((aligned(8)))
|
||||
#define ALIGN_16 __attribute__((aligned(16)))
|
||||
|
||||
// Some portability macros :)
|
||||
#define stricmp strcasecmp
|
||||
|
||||
#else
|
||||
|
||||
#error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler"
|
||||
|
||||
/*
|
||||
// Copy and uncomment this into another #elif section based on your compiler identification
|
||||
|
||||
// Explicitly mark classes as abstract (no instances can be created)
|
||||
#define abstract
|
||||
|
||||
// Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class)
|
||||
#define override
|
||||
|
||||
// Mark functions as obsolete, so that their usage results in a compile-time warning
|
||||
#define OBSOLETE
|
||||
|
||||
// Mark types / variables for alignment. Do the platforms need it?
|
||||
#define ALIGN_8
|
||||
#define ALIGN_16
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Integral types with predefined sizes:
|
||||
typedef long long Int64;
|
||||
typedef int Int32;
|
||||
typedef short Int16;
|
||||
|
||||
typedef unsigned long long UInt64;
|
||||
typedef unsigned int UInt32;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// A macro to disallow the copy constructor and operator= functions
|
||||
// This should be used in the private: declarations for any class that shouldn't allow copying itself
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName &); \
|
||||
void operator=(const TypeName &)
|
||||
|
||||
// A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc
|
||||
#define UNUSED(X) (void)(X)
|
||||
|
||||
|
||||
|
||||
|
||||
// OS-dependent stuff:
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
// Windows SDK defines min and max macros, messing up with our std::min and std::max usage
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
// Windows SDK defines GetFreeSpace as a constant, probably a Win16 API remnant
|
||||
#ifdef GetFreeSpace
|
||||
#undef GetFreeSpace
|
||||
#endif // GetFreeSpace
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h> // for mkdir
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define FILE_IO_PREFIX ""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// CRT stuff:
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// STL stuff:
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <ctime>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common headers (part 1, without macros):
|
||||
#include "../../source/StringUtils.h"
|
||||
#include "../../source/OSSupport/CriticalSection.h"
|
||||
#include "../../source/OSSupport/Semaphore.h"
|
||||
#include "../../source/OSSupport/Event.h"
|
||||
#include "../../source/OSSupport/IsThread.h"
|
||||
#include "../../source/OSSupport/File.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common definitions:
|
||||
|
||||
#define LOG(x,...) printf(x "\n", __VA_ARGS__)
|
||||
#define LOGERROR LOG
|
||||
#define LOGWARNING LOG
|
||||
#define LOGINFO LOG
|
||||
#define LOGWARN LOG
|
||||
|
||||
/// Evaluates to the number of elements in an array (compile-time!)
|
||||
#define ARRAYCOUNT(X) (sizeof(X) / sizeof(*(X)))
|
||||
|
||||
/// Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)" )
|
||||
#define KiB * 1024
|
||||
|
||||
/// Allows arithmetic expressions like "32 MiB" (but consider using parenthesis around it, "(32 MiB)" )
|
||||
#define MiB * 1024 * 1024
|
||||
|
||||
/// Faster than (int)floorf((float)x / (float)div)
|
||||
#define FAST_FLOOR_DIV( x, div ) ( (x) < 0 ? (((int)x / div) - 1) : ((int)x / div) )
|
||||
|
||||
// Own version of assert() that writes failed assertions to the log for review
|
||||
#ifdef _DEBUG
|
||||
#define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) )
|
||||
#else
|
||||
#define ASSERT(x) ((void)0)
|
||||
#endif
|
||||
|
||||
// Pretty much the same as ASSERT() but stays in Release builds
|
||||
#define VERIFY( x ) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), exit(1), 0 ) )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// A generic interface used mainly in ForEach() functions
|
||||
template <typename Type> class cItemCallback
|
||||
{
|
||||
public:
|
||||
/// Called for each item in the internal list; return true to stop the loop, or false to continue enumerating
|
||||
virtual bool Item(Type * a_Type) = 0;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common headers (part 2, with macros):
|
||||
#include "../../source/ChunkDef.h"
|
||||
#include "../../source/BlockID.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Globals.h
|
||||
|
||||
// This file gets included from every module in the project, so that global symbols may be introduced easily
|
||||
// Also used for precompiled header generation in MSVC environments
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Compiler-dependent stuff:
|
||||
#if defined(_MSC_VER)
|
||||
// MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether
|
||||
#pragma warning(disable:4481)
|
||||
|
||||
// Disable some warnings that we don't care about:
|
||||
#pragma warning(disable:4100)
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#define OBSOLETE __declspec(deprecated)
|
||||
|
||||
// No alignment needed in MSVC
|
||||
#define ALIGN_8
|
||||
#define ALIGN_16
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
// TODO: Can GCC explicitly mark classes as abstract (no instances can be created)?
|
||||
#define abstract
|
||||
|
||||
// TODO: Can GCC mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class)
|
||||
#define override
|
||||
|
||||
#define OBSOLETE __attribute__((deprecated))
|
||||
|
||||
#define ALIGN_8 __attribute__((aligned(8)))
|
||||
#define ALIGN_16 __attribute__((aligned(16)))
|
||||
|
||||
// Some portability macros :)
|
||||
#define stricmp strcasecmp
|
||||
|
||||
#else
|
||||
|
||||
#error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler"
|
||||
|
||||
/*
|
||||
// Copy and uncomment this into another #elif section based on your compiler identification
|
||||
|
||||
// Explicitly mark classes as abstract (no instances can be created)
|
||||
#define abstract
|
||||
|
||||
// Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class)
|
||||
#define override
|
||||
|
||||
// Mark functions as obsolete, so that their usage results in a compile-time warning
|
||||
#define OBSOLETE
|
||||
|
||||
// Mark types / variables for alignment. Do the platforms need it?
|
||||
#define ALIGN_8
|
||||
#define ALIGN_16
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Integral types with predefined sizes:
|
||||
typedef long long Int64;
|
||||
typedef int Int32;
|
||||
typedef short Int16;
|
||||
|
||||
typedef unsigned long long UInt64;
|
||||
typedef unsigned int UInt32;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// A macro to disallow the copy constructor and operator= functions
|
||||
// This should be used in the private: declarations for any class that shouldn't allow copying itself
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName &); \
|
||||
void operator=(const TypeName &)
|
||||
|
||||
// A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc
|
||||
#define UNUSED(X) (void)(X)
|
||||
|
||||
|
||||
|
||||
|
||||
// OS-dependent stuff:
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
// Windows SDK defines min and max macros, messing up with our std::min and std::max usage
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
// Windows SDK defines GetFreeSpace as a constant, probably a Win16 API remnant
|
||||
#ifdef GetFreeSpace
|
||||
#undef GetFreeSpace
|
||||
#endif // GetFreeSpace
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h> // for mkdir
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define FILE_IO_PREFIX ""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// CRT stuff:
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// STL stuff:
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <ctime>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common headers (part 1, without macros):
|
||||
#include "../../source/StringUtils.h"
|
||||
#include "../../source/OSSupport/CriticalSection.h"
|
||||
#include "../../source/OSSupport/Semaphore.h"
|
||||
#include "../../source/OSSupport/Event.h"
|
||||
#include "../../source/OSSupport/IsThread.h"
|
||||
#include "../../source/OSSupport/File.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common definitions:
|
||||
|
||||
#define LOG(x,...) printf(x "\n", __VA_ARGS__)
|
||||
#define LOGERROR LOG
|
||||
#define LOGWARNING LOG
|
||||
#define LOGINFO LOG
|
||||
#define LOGWARN LOG
|
||||
|
||||
/// Evaluates to the number of elements in an array (compile-time!)
|
||||
#define ARRAYCOUNT(X) (sizeof(X) / sizeof(*(X)))
|
||||
|
||||
/// Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)" )
|
||||
#define KiB * 1024
|
||||
|
||||
/// Allows arithmetic expressions like "32 MiB" (but consider using parenthesis around it, "(32 MiB)" )
|
||||
#define MiB * 1024 * 1024
|
||||
|
||||
/// Faster than (int)floorf((float)x / (float)div)
|
||||
#define FAST_FLOOR_DIV( x, div ) ( (x) < 0 ? (((int)x / div) - 1) : ((int)x / div) )
|
||||
|
||||
// Own version of assert() that writes failed assertions to the log for review
|
||||
#ifdef _DEBUG
|
||||
#define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) )
|
||||
#else
|
||||
#define ASSERT(x) ((void)0)
|
||||
#endif
|
||||
|
||||
// Pretty much the same as ASSERT() but stays in Release builds
|
||||
#define VERIFY( x ) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), exit(1), 0 ) )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// A generic interface used mainly in ForEach() functions
|
||||
template <typename Type> class cItemCallback
|
||||
{
|
||||
public:
|
||||
/// Called for each item in the internal list; return true to stop the loop, or false to continue enumerating
|
||||
virtual bool Item(Type * a_Type) = 0;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common headers (part 2, with macros):
|
||||
#include "../../source/ChunkDef.h"
|
||||
#include "../../source/BlockID.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,265 +1,265 @@
|
||||
|
||||
// HeightMap.cpp
|
||||
|
||||
// Implements the cHeightMap class representing a cCallback descendant that draws a B&W map of heights for the world
|
||||
|
||||
#include "Globals.h"
|
||||
#include "HeightMap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const unsigned char g_BMPHeader[] =
|
||||
{
|
||||
0x42, 0x4D, 0x36, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cHeightMap::cHeightMap(void) :
|
||||
m_CurrentRegionX(0),
|
||||
m_CurrentRegionZ(0),
|
||||
m_IsCurrentRegionValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cHeightMap::Finish(void)
|
||||
{
|
||||
if (m_IsCurrentRegionValid)
|
||||
{
|
||||
StartNewRegion(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cHeightMap::OnNewChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
int RegionX = (a_ChunkX < 0) ? (a_ChunkX - 31) / 32 : a_ChunkX / 32;
|
||||
int RegionZ = (a_ChunkZ < 0) ? (a_ChunkZ - 31) / 32 : a_ChunkZ / 32;
|
||||
if ((RegionX != m_CurrentRegionX) || (RegionZ != m_CurrentRegionZ))
|
||||
{
|
||||
if (m_IsCurrentRegionValid)
|
||||
{
|
||||
StartNewRegion(RegionX, RegionZ);
|
||||
}
|
||||
m_CurrentRegionX = RegionX;
|
||||
m_CurrentRegionZ = RegionZ;
|
||||
}
|
||||
m_IsCurrentRegionValid = true;
|
||||
m_CurrentChunkX = a_ChunkX;
|
||||
m_CurrentChunkZ = a_ChunkZ;
|
||||
m_CurrentChunkOffX = m_CurrentChunkX - m_CurrentRegionX * 32;
|
||||
m_CurrentChunkOffZ = m_CurrentChunkZ - m_CurrentRegionZ * 32;
|
||||
memset(m_BlockTypes, 0, sizeof(m_BlockTypes));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cHeightMap::OnHeightMap(const int * a_HeightMapBE)
|
||||
{
|
||||
ASSERT(m_CurrentChunkOffX >= 0);
|
||||
ASSERT(m_CurrentChunkOffX < 32);
|
||||
ASSERT(m_CurrentChunkOffZ >= 0);
|
||||
ASSERT(m_CurrentChunkOffZ < 32);
|
||||
int * BaseHeight = m_Height + m_CurrentChunkOffZ * 16 * 512 + m_CurrentChunkOffX * 16;
|
||||
for (int z = 0; z < 16; z++)
|
||||
{
|
||||
int * Row = BaseHeight + z * 512;
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
Row[x] = ntohl(a_HeightMapBE[z * 16 + x]);
|
||||
}
|
||||
} // for z
|
||||
return false; // Still want blockdata to remove trees from the heightmap
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cHeightMap::OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
)
|
||||
{
|
||||
// Copy the section data into the appropriate place in the internal buffer
|
||||
memcpy(m_BlockTypes + a_Y * 16 * 16 * 16, a_BlockTypes, 16 * 16 * 16);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cHeightMap::OnSectionsFinished(void)
|
||||
{
|
||||
// Remove trees from the heightmap:
|
||||
for (int z = 0; z < 16; z++)
|
||||
{
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
for (int y = m_Height[512 * (16 * m_CurrentChunkOffZ + z) + 16 * m_CurrentChunkOffX + x]; y >= 0; y--)
|
||||
{
|
||||
if (IsGround(m_BlockTypes[256 * y + 16 * z + x]))
|
||||
{
|
||||
m_Height[512 * (16 * m_CurrentChunkOffZ + z) + 16 * m_CurrentChunkOffX + x] = y;
|
||||
break; // for y
|
||||
}
|
||||
} // for y
|
||||
} // for x
|
||||
} // for z
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cHeightMap::StartNewRegion(int a_RegionX, int a_RegionZ)
|
||||
{
|
||||
AString FileName;
|
||||
Printf(FileName, "Height.%d.%d.bmp", m_CurrentRegionX, m_CurrentRegionZ);
|
||||
cFile f;
|
||||
if (!f.Open(FileName, cFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot open file \"%s\" for writing the height map. Data for this region lost.", FileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
f.Write(g_BMPHeader, sizeof(g_BMPHeader));
|
||||
for (int z = 0; z < 512; z++)
|
||||
{
|
||||
int RowData[512];
|
||||
int * HeightRow = m_Height + z * 512;
|
||||
for (int x = 0; x < 512; x++)
|
||||
{
|
||||
RowData[x] = std::max(std::min(HeightRow[x], 255), 0) * 0x010101;
|
||||
}
|
||||
f.Write(RowData, sizeof(RowData));
|
||||
} // for z
|
||||
}
|
||||
|
||||
memset(m_Height, 0, sizeof(m_Height));
|
||||
m_CurrentRegionX = a_RegionX;
|
||||
m_CurrentRegionZ = a_RegionZ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cHeightMap::IsGround(BLOCKTYPE a_BlockType)
|
||||
{
|
||||
// Name all blocks that are NOT ground, return false for them:
|
||||
switch (a_BlockType)
|
||||
{
|
||||
case E_BLOCK_AIR:
|
||||
case E_BLOCK_BED:
|
||||
case E_BLOCK_BREWING_STAND:
|
||||
case E_BLOCK_BROWN_MUSHROOM:
|
||||
case E_BLOCK_CACTUS:
|
||||
case E_BLOCK_CAKE:
|
||||
case E_BLOCK_CARROTS:
|
||||
case E_BLOCK_CAULDRON:
|
||||
case E_BLOCK_CHEST:
|
||||
case E_BLOCK_COBBLESTONE_WALL:
|
||||
case E_BLOCK_COBWEB:
|
||||
case E_BLOCK_COCOA_POD:
|
||||
case E_BLOCK_CROPS:
|
||||
case E_BLOCK_DEAD_BUSH:
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_DIRT:
|
||||
case E_BLOCK_DRAGON_EGG:
|
||||
case E_BLOCK_END_PORTAL:
|
||||
case E_BLOCK_ENDER_CHEST:
|
||||
case E_BLOCK_FENCE:
|
||||
case E_BLOCK_FENCE_GATE:
|
||||
case E_BLOCK_FIRE:
|
||||
case E_BLOCK_FLOWER_POT:
|
||||
case E_BLOCK_HEAD:
|
||||
case E_BLOCK_IRON_BARS:
|
||||
case E_BLOCK_LADDER:
|
||||
case E_BLOCK_LAVA:
|
||||
case E_BLOCK_LEAVES:
|
||||
case E_BLOCK_LEVER:
|
||||
case E_BLOCK_LILY_PAD:
|
||||
case E_BLOCK_LOG: // NOTE: This block is actually solid, but we don't want it because it's the thing that trees are made of, and we're getting rid of trees
|
||||
case E_BLOCK_MELON:
|
||||
case E_BLOCK_MELON_STEM:
|
||||
case E_BLOCK_NETHER_BRICK_FENCE:
|
||||
case E_BLOCK_NETHER_PORTAL:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
case E_BLOCK_PUMPKIN:
|
||||
case E_BLOCK_PUMPKIN_STEM:
|
||||
case E_BLOCK_RAIL:
|
||||
case E_BLOCK_RED_ROSE:
|
||||
case E_BLOCK_RED_MUSHROOM:
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_REDSTONE_TORCH_OFF:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_REEDS:
|
||||
case E_BLOCK_SAPLING:
|
||||
case E_BLOCK_SIGN_POST:
|
||||
case E_BLOCK_SNOW:
|
||||
case E_BLOCK_STATIONARY_LAVA:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
case E_BLOCK_TALL_GRASS:
|
||||
case E_BLOCK_TORCH:
|
||||
case E_BLOCK_TRIPWIRE:
|
||||
case E_BLOCK_TRIPWIRE_HOOK:
|
||||
case E_BLOCK_VINES:
|
||||
case E_BLOCK_WALLSIGN:
|
||||
case E_BLOCK_WATER:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
case E_BLOCK_YELLOW_FLOWER:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cHeightMapFactory:
|
||||
|
||||
cHeightMapFactory::~cHeightMapFactory()
|
||||
{
|
||||
// Force all threads to save their last regions:
|
||||
for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr)
|
||||
{
|
||||
((cHeightMap *)(*itr))->Finish();
|
||||
}
|
||||
// TODO: Join all the files into one giant image file
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// HeightMap.cpp
|
||||
|
||||
// Implements the cHeightMap class representing a cCallback descendant that draws a B&W map of heights for the world
|
||||
|
||||
#include "Globals.h"
|
||||
#include "HeightMap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const unsigned char g_BMPHeader[] =
|
||||
{
|
||||
0x42, 0x4D, 0x36, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cHeightMap::cHeightMap(void) :
|
||||
m_CurrentRegionX(0),
|
||||
m_CurrentRegionZ(0),
|
||||
m_IsCurrentRegionValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cHeightMap::Finish(void)
|
||||
{
|
||||
if (m_IsCurrentRegionValid)
|
||||
{
|
||||
StartNewRegion(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cHeightMap::OnNewChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
int RegionX = (a_ChunkX < 0) ? (a_ChunkX - 31) / 32 : a_ChunkX / 32;
|
||||
int RegionZ = (a_ChunkZ < 0) ? (a_ChunkZ - 31) / 32 : a_ChunkZ / 32;
|
||||
if ((RegionX != m_CurrentRegionX) || (RegionZ != m_CurrentRegionZ))
|
||||
{
|
||||
if (m_IsCurrentRegionValid)
|
||||
{
|
||||
StartNewRegion(RegionX, RegionZ);
|
||||
}
|
||||
m_CurrentRegionX = RegionX;
|
||||
m_CurrentRegionZ = RegionZ;
|
||||
}
|
||||
m_IsCurrentRegionValid = true;
|
||||
m_CurrentChunkX = a_ChunkX;
|
||||
m_CurrentChunkZ = a_ChunkZ;
|
||||
m_CurrentChunkOffX = m_CurrentChunkX - m_CurrentRegionX * 32;
|
||||
m_CurrentChunkOffZ = m_CurrentChunkZ - m_CurrentRegionZ * 32;
|
||||
memset(m_BlockTypes, 0, sizeof(m_BlockTypes));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cHeightMap::OnHeightMap(const int * a_HeightMapBE)
|
||||
{
|
||||
ASSERT(m_CurrentChunkOffX >= 0);
|
||||
ASSERT(m_CurrentChunkOffX < 32);
|
||||
ASSERT(m_CurrentChunkOffZ >= 0);
|
||||
ASSERT(m_CurrentChunkOffZ < 32);
|
||||
int * BaseHeight = m_Height + m_CurrentChunkOffZ * 16 * 512 + m_CurrentChunkOffX * 16;
|
||||
for (int z = 0; z < 16; z++)
|
||||
{
|
||||
int * Row = BaseHeight + z * 512;
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
Row[x] = ntohl(a_HeightMapBE[z * 16 + x]);
|
||||
}
|
||||
} // for z
|
||||
return false; // Still want blockdata to remove trees from the heightmap
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cHeightMap::OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
)
|
||||
{
|
||||
// Copy the section data into the appropriate place in the internal buffer
|
||||
memcpy(m_BlockTypes + a_Y * 16 * 16 * 16, a_BlockTypes, 16 * 16 * 16);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cHeightMap::OnSectionsFinished(void)
|
||||
{
|
||||
// Remove trees from the heightmap:
|
||||
for (int z = 0; z < 16; z++)
|
||||
{
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
for (int y = m_Height[512 * (16 * m_CurrentChunkOffZ + z) + 16 * m_CurrentChunkOffX + x]; y >= 0; y--)
|
||||
{
|
||||
if (IsGround(m_BlockTypes[256 * y + 16 * z + x]))
|
||||
{
|
||||
m_Height[512 * (16 * m_CurrentChunkOffZ + z) + 16 * m_CurrentChunkOffX + x] = y;
|
||||
break; // for y
|
||||
}
|
||||
} // for y
|
||||
} // for x
|
||||
} // for z
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cHeightMap::StartNewRegion(int a_RegionX, int a_RegionZ)
|
||||
{
|
||||
AString FileName;
|
||||
Printf(FileName, "Height.%d.%d.bmp", m_CurrentRegionX, m_CurrentRegionZ);
|
||||
cFile f;
|
||||
if (!f.Open(FileName, cFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot open file \"%s\" for writing the height map. Data for this region lost.", FileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
f.Write(g_BMPHeader, sizeof(g_BMPHeader));
|
||||
for (int z = 0; z < 512; z++)
|
||||
{
|
||||
int RowData[512];
|
||||
int * HeightRow = m_Height + z * 512;
|
||||
for (int x = 0; x < 512; x++)
|
||||
{
|
||||
RowData[x] = std::max(std::min(HeightRow[x], 255), 0) * 0x010101;
|
||||
}
|
||||
f.Write(RowData, sizeof(RowData));
|
||||
} // for z
|
||||
}
|
||||
|
||||
memset(m_Height, 0, sizeof(m_Height));
|
||||
m_CurrentRegionX = a_RegionX;
|
||||
m_CurrentRegionZ = a_RegionZ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cHeightMap::IsGround(BLOCKTYPE a_BlockType)
|
||||
{
|
||||
// Name all blocks that are NOT ground, return false for them:
|
||||
switch (a_BlockType)
|
||||
{
|
||||
case E_BLOCK_AIR:
|
||||
case E_BLOCK_BED:
|
||||
case E_BLOCK_BREWING_STAND:
|
||||
case E_BLOCK_BROWN_MUSHROOM:
|
||||
case E_BLOCK_CACTUS:
|
||||
case E_BLOCK_CAKE:
|
||||
case E_BLOCK_CARROTS:
|
||||
case E_BLOCK_CAULDRON:
|
||||
case E_BLOCK_CHEST:
|
||||
case E_BLOCK_COBBLESTONE_WALL:
|
||||
case E_BLOCK_COBWEB:
|
||||
case E_BLOCK_COCOA_POD:
|
||||
case E_BLOCK_CROPS:
|
||||
case E_BLOCK_DEAD_BUSH:
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_DIRT:
|
||||
case E_BLOCK_DRAGON_EGG:
|
||||
case E_BLOCK_END_PORTAL:
|
||||
case E_BLOCK_ENDER_CHEST:
|
||||
case E_BLOCK_FENCE:
|
||||
case E_BLOCK_FENCE_GATE:
|
||||
case E_BLOCK_FIRE:
|
||||
case E_BLOCK_FLOWER_POT:
|
||||
case E_BLOCK_HEAD:
|
||||
case E_BLOCK_IRON_BARS:
|
||||
case E_BLOCK_LADDER:
|
||||
case E_BLOCK_LAVA:
|
||||
case E_BLOCK_LEAVES:
|
||||
case E_BLOCK_LEVER:
|
||||
case E_BLOCK_LILY_PAD:
|
||||
case E_BLOCK_LOG: // NOTE: This block is actually solid, but we don't want it because it's the thing that trees are made of, and we're getting rid of trees
|
||||
case E_BLOCK_MELON:
|
||||
case E_BLOCK_MELON_STEM:
|
||||
case E_BLOCK_NETHER_BRICK_FENCE:
|
||||
case E_BLOCK_NETHER_PORTAL:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
case E_BLOCK_PUMPKIN:
|
||||
case E_BLOCK_PUMPKIN_STEM:
|
||||
case E_BLOCK_RAIL:
|
||||
case E_BLOCK_RED_ROSE:
|
||||
case E_BLOCK_RED_MUSHROOM:
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_REDSTONE_TORCH_OFF:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_REEDS:
|
||||
case E_BLOCK_SAPLING:
|
||||
case E_BLOCK_SIGN_POST:
|
||||
case E_BLOCK_SNOW:
|
||||
case E_BLOCK_STATIONARY_LAVA:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
case E_BLOCK_TALL_GRASS:
|
||||
case E_BLOCK_TORCH:
|
||||
case E_BLOCK_TRIPWIRE:
|
||||
case E_BLOCK_TRIPWIRE_HOOK:
|
||||
case E_BLOCK_VINES:
|
||||
case E_BLOCK_WALLSIGN:
|
||||
case E_BLOCK_WATER:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
case E_BLOCK_YELLOW_FLOWER:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cHeightMapFactory:
|
||||
|
||||
cHeightMapFactory::~cHeightMapFactory()
|
||||
{
|
||||
// Force all threads to save their last regions:
|
||||
for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr)
|
||||
{
|
||||
((cHeightMap *)(*itr))->Finish();
|
||||
}
|
||||
// TODO: Join all the files into one giant image file
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,81 +1,81 @@
|
||||
|
||||
// HeightMap.h
|
||||
|
||||
// Declares the cHeightMap class representing a cCallback descendant that draws a B&W map of heights for the world
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callback.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cHeightMap :
|
||||
public cCallback
|
||||
{
|
||||
public:
|
||||
cHeightMap(void);
|
||||
|
||||
void Finish(void);
|
||||
|
||||
protected:
|
||||
int m_CurrentChunkX; // Absolute chunk coords
|
||||
int m_CurrentChunkZ;
|
||||
int m_CurrentChunkOffX; // Chunk offset from the start of the region
|
||||
int m_CurrentChunkOffZ;
|
||||
int m_CurrentRegionX;
|
||||
int m_CurrentRegionZ;
|
||||
bool m_IsCurrentRegionValid;
|
||||
int m_Height[16 * 32 * 16 * 32]; ///< Height-map of the entire current region [x + 16 * 32 * z]
|
||||
BLOCKTYPE m_BlockTypes[16 * 16 * 256]; ///< Block data of the currently processed chunk (between OnSection() and OnSectionsFinished() )
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) override { return false; }
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override { return false; }
|
||||
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) override { return false; }
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) override { return false; }
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) override { return !a_Populated; } // If not populated, we don't want it!
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) { return false; }
|
||||
virtual bool OnHeightMap(const int * a_HeightMapBE) override;
|
||||
virtual bool OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
) override;
|
||||
virtual bool OnSectionsFinished(void) override;
|
||||
|
||||
void StartNewRegion(int a_RegionX, int a_RegionZ);
|
||||
|
||||
static bool IsGround(BLOCKTYPE a_BlockType);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cHeightMapFactory :
|
||||
public cCallbackFactory
|
||||
{
|
||||
public:
|
||||
virtual ~cHeightMapFactory();
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cHeightMap;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// HeightMap.h
|
||||
|
||||
// Declares the cHeightMap class representing a cCallback descendant that draws a B&W map of heights for the world
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callback.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cHeightMap :
|
||||
public cCallback
|
||||
{
|
||||
public:
|
||||
cHeightMap(void);
|
||||
|
||||
void Finish(void);
|
||||
|
||||
protected:
|
||||
int m_CurrentChunkX; // Absolute chunk coords
|
||||
int m_CurrentChunkZ;
|
||||
int m_CurrentChunkOffX; // Chunk offset from the start of the region
|
||||
int m_CurrentChunkOffZ;
|
||||
int m_CurrentRegionX;
|
||||
int m_CurrentRegionZ;
|
||||
bool m_IsCurrentRegionValid;
|
||||
int m_Height[16 * 32 * 16 * 32]; ///< Height-map of the entire current region [x + 16 * 32 * z]
|
||||
BLOCKTYPE m_BlockTypes[16 * 16 * 256]; ///< Block data of the currently processed chunk (between OnSection() and OnSectionsFinished() )
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) override { return false; }
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override { return false; }
|
||||
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) override { return false; }
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) override { return false; }
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) override { return !a_Populated; } // If not populated, we don't want it!
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) { return false; }
|
||||
virtual bool OnHeightMap(const int * a_HeightMapBE) override;
|
||||
virtual bool OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
) override;
|
||||
virtual bool OnSectionsFinished(void) override;
|
||||
|
||||
void StartNewRegion(int a_RegionX, int a_RegionZ);
|
||||
|
||||
static bool IsGround(BLOCKTYPE a_BlockType);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cHeightMapFactory :
|
||||
public cCallbackFactory
|
||||
{
|
||||
public:
|
||||
virtual ~cHeightMapFactory();
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cHeightMap;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,77 +1,77 @@
|
||||
|
||||
// Processor.h
|
||||
|
||||
// Interfaces to the cProcessor class representing the overall processor engine that manages threads, calls callbacks etc.
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cCallback;
|
||||
class cCallbackFactory;
|
||||
class cParsedNBT;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cProcessor
|
||||
{
|
||||
class cThread :
|
||||
public cIsThread
|
||||
{
|
||||
typedef cIsThread super;
|
||||
|
||||
cCallback & m_Callback;
|
||||
cProcessor & m_ParentProcessor;
|
||||
|
||||
// cIsThread override:
|
||||
virtual void Execute(void) override;
|
||||
|
||||
void ProcessFile(const AString & a_FileName);
|
||||
void ProcessFileData(const char * a_FileData, size_t a_Size, int a_ChunkBaseX, int a_ChunkBaseZ);
|
||||
void ProcessChunk(const char * a_FileData, int a_ChunkX, int a_ChunkZ, unsigned a_SectorStart, unsigned a_SectorSize, unsigned a_TimeStamp);
|
||||
void ProcessCompressedChunkData(int a_ChunkX, int a_ChunkZ, const char * a_CompressedData, int a_CompressedSize);
|
||||
void ProcessParsedChunkData(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT);
|
||||
|
||||
// The following processing parts return true if they were interrupted by the callback, causing the processing of current chunk to abort
|
||||
bool ProcessChunkSections(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT, int a_LevelTag);
|
||||
bool ProcessChunkEntities(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT, int a_LevelTag);
|
||||
bool ProcessChunkTileEntities(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT, int a_LevelTag);
|
||||
bool ProcessChunkTileTicks(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT, int a_LevelTag);
|
||||
|
||||
public:
|
||||
cThread(cCallback & a_Callback, cProcessor & a_ParentProcessor);
|
||||
} ;
|
||||
|
||||
typedef std::vector<cThread *> cThreads;
|
||||
|
||||
public:
|
||||
cProcessor(void);
|
||||
~cProcessor();
|
||||
|
||||
void ProcessWorld(const AString & a_WorldFolder, cCallbackFactory & a_CallbackFactory);
|
||||
|
||||
protected:
|
||||
bool m_IsShuttingDown; // If true, the threads should stop ASAP
|
||||
|
||||
cCriticalSection m_CS;
|
||||
AStringList m_FileQueue;
|
||||
|
||||
cThreads m_Threads;
|
||||
cEvent m_ThreadsHaveStarted; // This is signalled by each thread to notify the parent thread that it can start waiting for those threads
|
||||
|
||||
void PopulateFileQueue(const AString & a_WorldFolder);
|
||||
|
||||
AString GetOneFileName(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Processor.h
|
||||
|
||||
// Interfaces to the cProcessor class representing the overall processor engine that manages threads, calls callbacks etc.
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cCallback;
|
||||
class cCallbackFactory;
|
||||
class cParsedNBT;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cProcessor
|
||||
{
|
||||
class cThread :
|
||||
public cIsThread
|
||||
{
|
||||
typedef cIsThread super;
|
||||
|
||||
cCallback & m_Callback;
|
||||
cProcessor & m_ParentProcessor;
|
||||
|
||||
// cIsThread override:
|
||||
virtual void Execute(void) override;
|
||||
|
||||
void ProcessFile(const AString & a_FileName);
|
||||
void ProcessFileData(const char * a_FileData, size_t a_Size, int a_ChunkBaseX, int a_ChunkBaseZ);
|
||||
void ProcessChunk(const char * a_FileData, int a_ChunkX, int a_ChunkZ, unsigned a_SectorStart, unsigned a_SectorSize, unsigned a_TimeStamp);
|
||||
void ProcessCompressedChunkData(int a_ChunkX, int a_ChunkZ, const char * a_CompressedData, int a_CompressedSize);
|
||||
void ProcessParsedChunkData(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT);
|
||||
|
||||
// The following processing parts return true if they were interrupted by the callback, causing the processing of current chunk to abort
|
||||
bool ProcessChunkSections(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT, int a_LevelTag);
|
||||
bool ProcessChunkEntities(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT, int a_LevelTag);
|
||||
bool ProcessChunkTileEntities(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT, int a_LevelTag);
|
||||
bool ProcessChunkTileTicks(int a_ChunkX, int a_ChunkZ, cParsedNBT & a_NBT, int a_LevelTag);
|
||||
|
||||
public:
|
||||
cThread(cCallback & a_Callback, cProcessor & a_ParentProcessor);
|
||||
} ;
|
||||
|
||||
typedef std::vector<cThread *> cThreads;
|
||||
|
||||
public:
|
||||
cProcessor(void);
|
||||
~cProcessor();
|
||||
|
||||
void ProcessWorld(const AString & a_WorldFolder, cCallbackFactory & a_CallbackFactory);
|
||||
|
||||
protected:
|
||||
bool m_IsShuttingDown; // If true, the threads should stop ASAP
|
||||
|
||||
cCriticalSection m_CS;
|
||||
AStringList m_FileQueue;
|
||||
|
||||
cThreads m_Threads;
|
||||
cEvent m_ThreadsHaveStarted; // This is signalled by each thread to notify the parent thread that it can start waiting for those threads
|
||||
|
||||
void PopulateFileQueue(const AString & a_WorldFolder);
|
||||
|
||||
AString GetOneFileName(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,279 +1,279 @@
|
||||
|
||||
// SpringStats.cpp
|
||||
|
||||
// Implements the cSpringStats class representing a cCallback descendant that collects statistics on lava and water springs
|
||||
|
||||
#include "Globals.h"
|
||||
#include "SpringStats.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cSpringStats::cStats
|
||||
|
||||
cSpringStats::cStats::cStats(void) :
|
||||
m_TotalChunks(0)
|
||||
{
|
||||
memset(m_LavaSprings, 0, sizeof(m_LavaSprings));
|
||||
memset(m_WaterSprings, 0, sizeof(m_WaterSprings));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSpringStats::cStats::Add(const cSpringStats::cStats & a_Other)
|
||||
{
|
||||
m_TotalChunks += a_Other.m_TotalChunks;
|
||||
for (int Biome = 0; Biome < 256; Biome++)
|
||||
{
|
||||
for (int Height = 0; Height < 256; Height++)
|
||||
{
|
||||
m_LavaSprings[Biome][Height] += a_Other.m_LavaSprings[Biome][Height];
|
||||
m_WaterSprings[Biome][Height] += a_Other.m_WaterSprings[Biome][Height];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cSpringStats:
|
||||
|
||||
cSpringStats::cSpringStats(void) :
|
||||
m_AreBiomesValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cSpringStats::OnNewChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
memset(m_BlockTypes, 0, sizeof(m_BlockTypes));
|
||||
m_AreBiomesValid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cSpringStats::OnBiomes(const unsigned char * a_BiomeData)
|
||||
{
|
||||
memcpy(m_Biomes, a_BiomeData, sizeof(m_Biomes));
|
||||
m_AreBiomesValid = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cSpringStats::OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
)
|
||||
{
|
||||
memcpy(m_BlockTypes + ((int)a_Y) * 16 * 16 * 16, a_BlockTypes, 16 * 16 * 16);
|
||||
memcpy(m_BlockMetas + ((int)a_Y) * 16 * 16 * 16 / 2, a_BlockMeta, 16 * 16 * 16 / 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cSpringStats::OnSectionsFinished(void)
|
||||
{
|
||||
if (!m_AreBiomesValid)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calc the spring stats:
|
||||
for (int y = 1; y < 255; y++)
|
||||
{
|
||||
int BaseY = y * 16 * 16;
|
||||
for (int z = 1; z < 15; z++)
|
||||
{
|
||||
int Base = BaseY + z * 16;
|
||||
for (int x = 1; x < 15; x++)
|
||||
{
|
||||
if (cChunkDef::GetNibble(m_BlockMetas, Base + x) != 0)
|
||||
{
|
||||
// Not a source block
|
||||
continue;
|
||||
}
|
||||
switch (m_BlockTypes[Base + x])
|
||||
{
|
||||
case E_BLOCK_WATER:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
{
|
||||
TestSpring(x, y, z, m_Stats.m_WaterSprings);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_LAVA:
|
||||
case E_BLOCK_STATIONARY_LAVA:
|
||||
{
|
||||
TestSpring(x, y, z, m_Stats.m_LavaSprings);
|
||||
break;
|
||||
}
|
||||
} // switch (BlockType)
|
||||
} // for x
|
||||
} // for z
|
||||
} // for y
|
||||
m_Stats.m_TotalChunks += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSpringStats::TestSpring(int a_RelX, int a_RelY, int a_RelZ, cSpringStats::cStats::SpringStats & a_Stats)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
int x, y, z;
|
||||
} Coords[] =
|
||||
{
|
||||
{-1, 0, 0},
|
||||
{ 1, 0, 0},
|
||||
{ 0, -1, 0},
|
||||
{ 0, 1, 0},
|
||||
{ 0, 0, -1},
|
||||
{ 0, 0, 1},
|
||||
} ;
|
||||
bool HasFluidNextToIt = false;
|
||||
for (int i = 0; i < ARRAYCOUNT(Coords); i++)
|
||||
{
|
||||
switch (cChunkDef::GetBlock(m_BlockTypes, a_RelX + Coords[i].x, a_RelY + Coords[i].y, a_RelZ + Coords[i].z))
|
||||
{
|
||||
case E_BLOCK_WATER:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
case E_BLOCK_LAVA:
|
||||
case E_BLOCK_STATIONARY_LAVA:
|
||||
{
|
||||
if (cChunkDef::GetNibble(m_BlockMetas, a_RelX + Coords[i].x, a_RelY + Coords[i].y, a_RelZ + Coords[i].z) == 0)
|
||||
{
|
||||
// There is another source block next to this, so this is not a spring
|
||||
return;
|
||||
}
|
||||
HasFluidNextToIt = true;
|
||||
}
|
||||
} // switch (BlockType)
|
||||
} // for i - Coords[]
|
||||
|
||||
if (!HasFluidNextToIt)
|
||||
{
|
||||
// Surrounded by solids on all sides, this is probably not a spring,
|
||||
// but rather a bedrocked lake or something similar. Dont want.
|
||||
return;
|
||||
}
|
||||
|
||||
// No source blocks next to the specified block, so it is a spring. Add it to stats:
|
||||
a_Stats[a_RelY][((unsigned char *)m_Biomes)[a_RelX + 16 * a_RelZ]] += 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cSpringStatsFactory:
|
||||
|
||||
cSpringStatsFactory::~cSpringStatsFactory()
|
||||
{
|
||||
LOG("cSpringStats:");
|
||||
LOG(" Joining results...");
|
||||
JoinResults();
|
||||
LOG(" Total %llu chunks went through", m_CombinedStats.m_TotalChunks);
|
||||
|
||||
// Save statistics:
|
||||
LOG(" Saving statistics into files:");
|
||||
LOG(" Springs.xls");
|
||||
SaveTotals("Springs.xls");
|
||||
LOG(" BiomeWaterSprings.xls");
|
||||
SaveStatistics(m_CombinedStats.m_WaterSprings, "BiomeWaterSprings.xls");
|
||||
LOG(" BiomeLavaSprings.xls");
|
||||
SaveStatistics(m_CombinedStats.m_LavaSprings, "BiomeLavaSprings.xls");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSpringStatsFactory::JoinResults(void)
|
||||
{
|
||||
for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr)
|
||||
{
|
||||
m_CombinedStats.Add(((cSpringStats *)(*itr))->GetStats());
|
||||
} // for itr - m_Callbacks[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSpringStatsFactory::SaveTotals(const AString & a_FileName)
|
||||
{
|
||||
cFile f(a_FileName, cFile::fmWrite);
|
||||
if (!f.IsOpen())
|
||||
{
|
||||
LOG("Cannot open file \"%s\" for writing!", a_FileName.c_str());
|
||||
return;
|
||||
}
|
||||
f.Printf("Height\tWater\tLava\n");
|
||||
for (int Height = 0; Height < 256; Height++)
|
||||
{
|
||||
UInt64 TotalW = 0;
|
||||
UInt64 TotalL = 0;
|
||||
for (int Biome = 0; Biome < 256; Biome++)
|
||||
{
|
||||
TotalW += m_CombinedStats.m_WaterSprings[Height][Biome];
|
||||
TotalL += m_CombinedStats.m_LavaSprings[Height][Biome];
|
||||
}
|
||||
f.Printf("%d\t%llu\t%llu\n", Height, TotalW, TotalL);
|
||||
}
|
||||
f.Printf("\n# Chunks\t%llu", m_CombinedStats.m_TotalChunks);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSpringStatsFactory::SaveStatistics(const cSpringStats::cStats::SpringStats & a_Stats, const AString & a_FileName)
|
||||
{
|
||||
cFile f(a_FileName, cFile::fmWrite);
|
||||
if (!f.IsOpen())
|
||||
{
|
||||
LOG("Cannot open file \"%s\" for writing!", a_FileName.c_str());
|
||||
return;
|
||||
}
|
||||
for (int Height = 0; Height < 256; Height++)
|
||||
{
|
||||
AString Line;
|
||||
Line.reserve(2000);
|
||||
Printf(Line, "%d\t", Height);
|
||||
for (int Biome = 0; Biome < 256; Biome++)
|
||||
{
|
||||
AppendPrintf(Line, "%llu\t", a_Stats[Height][Biome]);
|
||||
}
|
||||
Line.append("\n");
|
||||
f.Write(Line.c_str(), Line.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// SpringStats.cpp
|
||||
|
||||
// Implements the cSpringStats class representing a cCallback descendant that collects statistics on lava and water springs
|
||||
|
||||
#include "Globals.h"
|
||||
#include "SpringStats.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cSpringStats::cStats
|
||||
|
||||
cSpringStats::cStats::cStats(void) :
|
||||
m_TotalChunks(0)
|
||||
{
|
||||
memset(m_LavaSprings, 0, sizeof(m_LavaSprings));
|
||||
memset(m_WaterSprings, 0, sizeof(m_WaterSprings));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSpringStats::cStats::Add(const cSpringStats::cStats & a_Other)
|
||||
{
|
||||
m_TotalChunks += a_Other.m_TotalChunks;
|
||||
for (int Biome = 0; Biome < 256; Biome++)
|
||||
{
|
||||
for (int Height = 0; Height < 256; Height++)
|
||||
{
|
||||
m_LavaSprings[Biome][Height] += a_Other.m_LavaSprings[Biome][Height];
|
||||
m_WaterSprings[Biome][Height] += a_Other.m_WaterSprings[Biome][Height];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cSpringStats:
|
||||
|
||||
cSpringStats::cSpringStats(void) :
|
||||
m_AreBiomesValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cSpringStats::OnNewChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
memset(m_BlockTypes, 0, sizeof(m_BlockTypes));
|
||||
m_AreBiomesValid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cSpringStats::OnBiomes(const unsigned char * a_BiomeData)
|
||||
{
|
||||
memcpy(m_Biomes, a_BiomeData, sizeof(m_Biomes));
|
||||
m_AreBiomesValid = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cSpringStats::OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
)
|
||||
{
|
||||
memcpy(m_BlockTypes + ((int)a_Y) * 16 * 16 * 16, a_BlockTypes, 16 * 16 * 16);
|
||||
memcpy(m_BlockMetas + ((int)a_Y) * 16 * 16 * 16 / 2, a_BlockMeta, 16 * 16 * 16 / 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cSpringStats::OnSectionsFinished(void)
|
||||
{
|
||||
if (!m_AreBiomesValid)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calc the spring stats:
|
||||
for (int y = 1; y < 255; y++)
|
||||
{
|
||||
int BaseY = y * 16 * 16;
|
||||
for (int z = 1; z < 15; z++)
|
||||
{
|
||||
int Base = BaseY + z * 16;
|
||||
for (int x = 1; x < 15; x++)
|
||||
{
|
||||
if (cChunkDef::GetNibble(m_BlockMetas, Base + x) != 0)
|
||||
{
|
||||
// Not a source block
|
||||
continue;
|
||||
}
|
||||
switch (m_BlockTypes[Base + x])
|
||||
{
|
||||
case E_BLOCK_WATER:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
{
|
||||
TestSpring(x, y, z, m_Stats.m_WaterSprings);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_LAVA:
|
||||
case E_BLOCK_STATIONARY_LAVA:
|
||||
{
|
||||
TestSpring(x, y, z, m_Stats.m_LavaSprings);
|
||||
break;
|
||||
}
|
||||
} // switch (BlockType)
|
||||
} // for x
|
||||
} // for z
|
||||
} // for y
|
||||
m_Stats.m_TotalChunks += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSpringStats::TestSpring(int a_RelX, int a_RelY, int a_RelZ, cSpringStats::cStats::SpringStats & a_Stats)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
int x, y, z;
|
||||
} Coords[] =
|
||||
{
|
||||
{-1, 0, 0},
|
||||
{ 1, 0, 0},
|
||||
{ 0, -1, 0},
|
||||
{ 0, 1, 0},
|
||||
{ 0, 0, -1},
|
||||
{ 0, 0, 1},
|
||||
} ;
|
||||
bool HasFluidNextToIt = false;
|
||||
for (int i = 0; i < ARRAYCOUNT(Coords); i++)
|
||||
{
|
||||
switch (cChunkDef::GetBlock(m_BlockTypes, a_RelX + Coords[i].x, a_RelY + Coords[i].y, a_RelZ + Coords[i].z))
|
||||
{
|
||||
case E_BLOCK_WATER:
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
case E_BLOCK_LAVA:
|
||||
case E_BLOCK_STATIONARY_LAVA:
|
||||
{
|
||||
if (cChunkDef::GetNibble(m_BlockMetas, a_RelX + Coords[i].x, a_RelY + Coords[i].y, a_RelZ + Coords[i].z) == 0)
|
||||
{
|
||||
// There is another source block next to this, so this is not a spring
|
||||
return;
|
||||
}
|
||||
HasFluidNextToIt = true;
|
||||
}
|
||||
} // switch (BlockType)
|
||||
} // for i - Coords[]
|
||||
|
||||
if (!HasFluidNextToIt)
|
||||
{
|
||||
// Surrounded by solids on all sides, this is probably not a spring,
|
||||
// but rather a bedrocked lake or something similar. Dont want.
|
||||
return;
|
||||
}
|
||||
|
||||
// No source blocks next to the specified block, so it is a spring. Add it to stats:
|
||||
a_Stats[a_RelY][((unsigned char *)m_Biomes)[a_RelX + 16 * a_RelZ]] += 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cSpringStatsFactory:
|
||||
|
||||
cSpringStatsFactory::~cSpringStatsFactory()
|
||||
{
|
||||
LOG("cSpringStats:");
|
||||
LOG(" Joining results...");
|
||||
JoinResults();
|
||||
LOG(" Total %llu chunks went through", m_CombinedStats.m_TotalChunks);
|
||||
|
||||
// Save statistics:
|
||||
LOG(" Saving statistics into files:");
|
||||
LOG(" Springs.xls");
|
||||
SaveTotals("Springs.xls");
|
||||
LOG(" BiomeWaterSprings.xls");
|
||||
SaveStatistics(m_CombinedStats.m_WaterSprings, "BiomeWaterSprings.xls");
|
||||
LOG(" BiomeLavaSprings.xls");
|
||||
SaveStatistics(m_CombinedStats.m_LavaSprings, "BiomeLavaSprings.xls");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSpringStatsFactory::JoinResults(void)
|
||||
{
|
||||
for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr)
|
||||
{
|
||||
m_CombinedStats.Add(((cSpringStats *)(*itr))->GetStats());
|
||||
} // for itr - m_Callbacks[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSpringStatsFactory::SaveTotals(const AString & a_FileName)
|
||||
{
|
||||
cFile f(a_FileName, cFile::fmWrite);
|
||||
if (!f.IsOpen())
|
||||
{
|
||||
LOG("Cannot open file \"%s\" for writing!", a_FileName.c_str());
|
||||
return;
|
||||
}
|
||||
f.Printf("Height\tWater\tLava\n");
|
||||
for (int Height = 0; Height < 256; Height++)
|
||||
{
|
||||
UInt64 TotalW = 0;
|
||||
UInt64 TotalL = 0;
|
||||
for (int Biome = 0; Biome < 256; Biome++)
|
||||
{
|
||||
TotalW += m_CombinedStats.m_WaterSprings[Height][Biome];
|
||||
TotalL += m_CombinedStats.m_LavaSprings[Height][Biome];
|
||||
}
|
||||
f.Printf("%d\t%llu\t%llu\n", Height, TotalW, TotalL);
|
||||
}
|
||||
f.Printf("\n# Chunks\t%llu", m_CombinedStats.m_TotalChunks);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSpringStatsFactory::SaveStatistics(const cSpringStats::cStats::SpringStats & a_Stats, const AString & a_FileName)
|
||||
{
|
||||
cFile f(a_FileName, cFile::fmWrite);
|
||||
if (!f.IsOpen())
|
||||
{
|
||||
LOG("Cannot open file \"%s\" for writing!", a_FileName.c_str());
|
||||
return;
|
||||
}
|
||||
for (int Height = 0; Height < 256; Height++)
|
||||
{
|
||||
AString Line;
|
||||
Line.reserve(2000);
|
||||
Printf(Line, "%d\t", Height);
|
||||
for (int Biome = 0; Biome < 256; Biome++)
|
||||
{
|
||||
AppendPrintf(Line, "%llu\t", a_Stats[Height][Biome]);
|
||||
}
|
||||
Line.append("\n");
|
||||
f.Write(Line.c_str(), Line.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,102 +1,102 @@
|
||||
|
||||
// SpringStats.h
|
||||
|
||||
// Declares the cSpringStats class representing a cCallback descendant that collects statistics on lava and water springs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callback.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cSpringStats :
|
||||
public cCallback
|
||||
{
|
||||
public:
|
||||
class cStats
|
||||
{
|
||||
public:
|
||||
/// Per-height, per-biome frequencies of springs
|
||||
typedef UInt64 SpringStats[256][256];
|
||||
|
||||
SpringStats m_LavaSprings;
|
||||
SpringStats m_WaterSprings;
|
||||
|
||||
UInt64 m_TotalChunks; ///< Total number of chunks that are fully processed through this callback(OnSectionsFinished())
|
||||
|
||||
cStats(void);
|
||||
void Add(const cStats & a_Other);
|
||||
} ;
|
||||
|
||||
cSpringStats(void);
|
||||
|
||||
const cStats & GetStats(void) const { return m_Stats; }
|
||||
|
||||
protected:
|
||||
|
||||
BLOCKTYPE m_BlockTypes[16 * 16 * 256];
|
||||
NIBBLETYPE m_BlockMetas[16 * 16 * 256 / 2];
|
||||
char m_Biomes[16 * 16];
|
||||
bool m_AreBiomesValid;
|
||||
|
||||
cStats m_Stats;
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) override { return false; }
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override { return false; }
|
||||
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) override { return false; }
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) override { return false; }
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) override { return !a_Populated; } // If not populated, we don't want it!
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) override;
|
||||
virtual bool OnHeightMap(const int * a_HeightMap) override { return false; }
|
||||
virtual bool OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
) override;
|
||||
virtual bool OnSectionsFinished(void) override;
|
||||
|
||||
/// Tests the specified block, if it appears to be a spring, it is added to a_Stats
|
||||
void TestSpring(int a_RelX, int a_RelY, int a_RelZ, cStats::SpringStats & a_Stats);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cSpringStatsFactory :
|
||||
public cCallbackFactory
|
||||
{
|
||||
public:
|
||||
virtual ~cSpringStatsFactory();
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cSpringStats;
|
||||
}
|
||||
|
||||
cSpringStats::cStats m_CombinedStats;
|
||||
|
||||
void JoinResults(void);
|
||||
|
||||
/// Saves total per-height data (summed through biomes) for both spring types to the file
|
||||
void SaveTotals(const AString & a_FileName);
|
||||
|
||||
/// Saves complete per-height, per-biome statistics for the springs to the file
|
||||
void SaveStatistics(const cSpringStats::cStats::SpringStats & a_Stats, const AString & a_FileName);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// SpringStats.h
|
||||
|
||||
// Declares the cSpringStats class representing a cCallback descendant that collects statistics on lava and water springs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callback.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cSpringStats :
|
||||
public cCallback
|
||||
{
|
||||
public:
|
||||
class cStats
|
||||
{
|
||||
public:
|
||||
/// Per-height, per-biome frequencies of springs
|
||||
typedef UInt64 SpringStats[256][256];
|
||||
|
||||
SpringStats m_LavaSprings;
|
||||
SpringStats m_WaterSprings;
|
||||
|
||||
UInt64 m_TotalChunks; ///< Total number of chunks that are fully processed through this callback(OnSectionsFinished())
|
||||
|
||||
cStats(void);
|
||||
void Add(const cStats & a_Other);
|
||||
} ;
|
||||
|
||||
cSpringStats(void);
|
||||
|
||||
const cStats & GetStats(void) const { return m_Stats; }
|
||||
|
||||
protected:
|
||||
|
||||
BLOCKTYPE m_BlockTypes[16 * 16 * 256];
|
||||
NIBBLETYPE m_BlockMetas[16 * 16 * 256 / 2];
|
||||
char m_Biomes[16 * 16];
|
||||
bool m_AreBiomesValid;
|
||||
|
||||
cStats m_Stats;
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) override { return false; }
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override { return false; }
|
||||
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) override { return false; }
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) override { return false; }
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) override { return !a_Populated; } // If not populated, we don't want it!
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) override;
|
||||
virtual bool OnHeightMap(const int * a_HeightMap) override { return false; }
|
||||
virtual bool OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
) override;
|
||||
virtual bool OnSectionsFinished(void) override;
|
||||
|
||||
/// Tests the specified block, if it appears to be a spring, it is added to a_Stats
|
||||
void TestSpring(int a_RelX, int a_RelY, int a_RelZ, cStats::SpringStats & a_Stats);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cSpringStatsFactory :
|
||||
public cCallbackFactory
|
||||
{
|
||||
public:
|
||||
virtual ~cSpringStatsFactory();
|
||||
|
||||
virtual cCallback * CreateNewCallback(void) override
|
||||
{
|
||||
return new cSpringStats;
|
||||
}
|
||||
|
||||
cSpringStats::cStats m_CombinedStats;
|
||||
|
||||
void JoinResults(void);
|
||||
|
||||
/// Saves total per-height data (summed through biomes) for both spring types to the file
|
||||
void SaveTotals(const AString & a_FileName);
|
||||
|
||||
/// Saves complete per-height, per-biome statistics for the springs to the file
|
||||
void SaveStatistics(const cSpringStats::cStats::SpringStats & a_Stats, const AString & a_FileName);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,138 +1,138 @@
|
||||
|
||||
// Statistics.h
|
||||
|
||||
// Interfaces to the cStatistics class representing a statistics-collecting callback
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callback.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cStatistics :
|
||||
public cCallback
|
||||
{
|
||||
public:
|
||||
class cStats
|
||||
{
|
||||
public:
|
||||
UInt64 m_TotalChunks; // Total number of chunks that go through this callback (OnNewChunk())
|
||||
UInt64 m_BiomeCounts[256];
|
||||
UInt64 m_BlockCounts[256][256]; // First dimension is the biome, second dimension is BlockType
|
||||
UInt64 m_BiomeNumChunks; // Num chunks that have been processed for biome stats
|
||||
UInt64 m_BlockNumChunks; // Num chunks that have been processed for block stats
|
||||
UInt64 m_NumEntities;
|
||||
UInt64 m_NumTileEntities;
|
||||
UInt64 m_NumTileTicks;
|
||||
int m_MinChunkX, m_MaxChunkX; // X coords range
|
||||
int m_MinChunkZ, m_MaxChunkZ; // Z coords range
|
||||
|
||||
Int64 m;
|
||||
UInt64 m_SpawnerEntity[entMax + 1];
|
||||
|
||||
cStats(void);
|
||||
void Add(const cStats & a_Stats);
|
||||
void UpdateCoordsRange(int a_ChunkX, int a_ChunkZ);
|
||||
} ;
|
||||
|
||||
cStatistics(void);
|
||||
|
||||
const cStats & GetStats(void) const { return m_Stats; }
|
||||
|
||||
protected:
|
||||
cStats m_Stats;
|
||||
|
||||
bool m_IsBiomesValid; // Set to true in OnBiomes(), reset to false in OnNewChunk(); if true, the m_BiomeData is valid for the current chunk
|
||||
unsigned char m_BiomeData[16 * 16];
|
||||
bool m_IsFirstSectionInChunk; // True if there was no section in the chunk yet. Set by OnNewChunk(), reset by OnSection()
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) override { return false; }
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override { return false; }
|
||||
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) override { return false; }
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) override { return false; }
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) override { return !a_Populated; } // If not populated, we don't want it!
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) override;
|
||||
virtual bool OnHeightMap(const int * a_HeightMap) override { return false; }
|
||||
virtual bool OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
) override;
|
||||
|
||||
virtual bool OnEmptySection(unsigned char a_Y) override;
|
||||
|
||||
virtual bool OnEntity(
|
||||
const AString & a_EntityType,
|
||||
double a_PosX, double a_PosY, double a_PosZ,
|
||||
double a_SpeedX, double a_SpeedY, double a_SpeedZ,
|
||||
float a_Yaw, float a_Pitch,
|
||||
float a_FallDistance,
|
||||
short a_FireTicksLeft,
|
||||
short a_AirTicks,
|
||||
char a_IsOnGround,
|
||||
cParsedNBT & a_NBT,
|
||||
int a_NBTTag
|
||||
) override;
|
||||
|
||||
virtual bool OnTileEntity(
|
||||
const AString & a_EntityType,
|
||||
int a_PosX, int a_PosY, int a_PosZ,
|
||||
cParsedNBT & a_NBT,
|
||||
int a_NBTTag
|
||||
) override;
|
||||
|
||||
virtual bool OnTileTick(
|
||||
int a_BlockType,
|
||||
int a_TicksLeft,
|
||||
int a_PosX, int a_PosY, int a_PosZ
|
||||
) override;
|
||||
|
||||
void OnSpawner(cParsedNBT & a_NBT, int a_TileEntityTag);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cStatisticsFactory :
|
||||
public cCallbackFactory
|
||||
{
|
||||
public:
|
||||
cStatisticsFactory(void);
|
||||
virtual ~cStatisticsFactory();
|
||||
|
||||
virtual cCallback * CreateNewCallback(void)
|
||||
{
|
||||
return new cStatistics;
|
||||
}
|
||||
|
||||
protected:
|
||||
// The results, combined, are stored here:
|
||||
cStatistics::cStats m_CombinedStats;
|
||||
|
||||
clock_t m_BeginTick;
|
||||
|
||||
void JoinResults(void);
|
||||
void SaveBiomes(void);
|
||||
void SaveBlockTypes(void);
|
||||
void SaveBiomeBlockTypes(void);
|
||||
void SaveStatistics(void);
|
||||
void SaveSpawners(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Statistics.h
|
||||
|
||||
// Interfaces to the cStatistics class representing a statistics-collecting callback
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callback.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cStatistics :
|
||||
public cCallback
|
||||
{
|
||||
public:
|
||||
class cStats
|
||||
{
|
||||
public:
|
||||
UInt64 m_TotalChunks; // Total number of chunks that go through this callback (OnNewChunk())
|
||||
UInt64 m_BiomeCounts[256];
|
||||
UInt64 m_BlockCounts[256][256]; // First dimension is the biome, second dimension is BlockType
|
||||
UInt64 m_BiomeNumChunks; // Num chunks that have been processed for biome stats
|
||||
UInt64 m_BlockNumChunks; // Num chunks that have been processed for block stats
|
||||
UInt64 m_NumEntities;
|
||||
UInt64 m_NumTileEntities;
|
||||
UInt64 m_NumTileTicks;
|
||||
int m_MinChunkX, m_MaxChunkX; // X coords range
|
||||
int m_MinChunkZ, m_MaxChunkZ; // Z coords range
|
||||
|
||||
Int64 m;
|
||||
UInt64 m_SpawnerEntity[entMax + 1];
|
||||
|
||||
cStats(void);
|
||||
void Add(const cStats & a_Stats);
|
||||
void UpdateCoordsRange(int a_ChunkX, int a_ChunkZ);
|
||||
} ;
|
||||
|
||||
cStatistics(void);
|
||||
|
||||
const cStats & GetStats(void) const { return m_Stats; }
|
||||
|
||||
protected:
|
||||
cStats m_Stats;
|
||||
|
||||
bool m_IsBiomesValid; // Set to true in OnBiomes(), reset to false in OnNewChunk(); if true, the m_BiomeData is valid for the current chunk
|
||||
unsigned char m_BiomeData[16 * 16];
|
||||
bool m_IsFirstSectionInChunk; // True if there was no section in the chunk yet. Set by OnNewChunk(), reset by OnSection()
|
||||
|
||||
// cCallback overrides:
|
||||
virtual bool OnNewChunk(int a_ChunkX, int a_ChunkZ) override;
|
||||
virtual bool OnHeader(int a_FileOffset, unsigned char a_NumSectors, int a_Timestamp) override { return false; }
|
||||
virtual bool OnCompressedDataSizePos(int a_CompressedDataSize, int a_DataOffset, char a_CompressionMethod) override { return false; }
|
||||
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override { return false; }
|
||||
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) override { return false; }
|
||||
virtual bool OnLastUpdate(Int64 a_LastUpdate) override { return false; }
|
||||
virtual bool OnTerrainPopulated(bool a_Populated) override { return !a_Populated; } // If not populated, we don't want it!
|
||||
virtual bool OnBiomes(const unsigned char * a_BiomeData) override;
|
||||
virtual bool OnHeightMap(const int * a_HeightMap) override { return false; }
|
||||
virtual bool OnSection(
|
||||
unsigned char a_Y,
|
||||
const BLOCKTYPE * a_BlockTypes,
|
||||
const NIBBLETYPE * a_BlockAdditional,
|
||||
const NIBBLETYPE * a_BlockMeta,
|
||||
const NIBBLETYPE * a_BlockLight,
|
||||
const NIBBLETYPE * a_BlockSkyLight
|
||||
) override;
|
||||
|
||||
virtual bool OnEmptySection(unsigned char a_Y) override;
|
||||
|
||||
virtual bool OnEntity(
|
||||
const AString & a_EntityType,
|
||||
double a_PosX, double a_PosY, double a_PosZ,
|
||||
double a_SpeedX, double a_SpeedY, double a_SpeedZ,
|
||||
float a_Yaw, float a_Pitch,
|
||||
float a_FallDistance,
|
||||
short a_FireTicksLeft,
|
||||
short a_AirTicks,
|
||||
char a_IsOnGround,
|
||||
cParsedNBT & a_NBT,
|
||||
int a_NBTTag
|
||||
) override;
|
||||
|
||||
virtual bool OnTileEntity(
|
||||
const AString & a_EntityType,
|
||||
int a_PosX, int a_PosY, int a_PosZ,
|
||||
cParsedNBT & a_NBT,
|
||||
int a_NBTTag
|
||||
) override;
|
||||
|
||||
virtual bool OnTileTick(
|
||||
int a_BlockType,
|
||||
int a_TicksLeft,
|
||||
int a_PosX, int a_PosY, int a_PosZ
|
||||
) override;
|
||||
|
||||
void OnSpawner(cParsedNBT & a_NBT, int a_TileEntityTag);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cStatisticsFactory :
|
||||
public cCallbackFactory
|
||||
{
|
||||
public:
|
||||
cStatisticsFactory(void);
|
||||
virtual ~cStatisticsFactory();
|
||||
|
||||
virtual cCallback * CreateNewCallback(void)
|
||||
{
|
||||
return new cStatistics;
|
||||
}
|
||||
|
||||
protected:
|
||||
// The results, combined, are stored here:
|
||||
cStatistics::cStats m_CombinedStats;
|
||||
|
||||
clock_t m_BeginTick;
|
||||
|
||||
void JoinResults(void);
|
||||
void SaveBiomes(void);
|
||||
void SaveBlockTypes(void);
|
||||
void SaveBiomeBlockTypes(void);
|
||||
void SaveStatistics(void);
|
||||
void SaveSpawners(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,291 +1,291 @@
|
||||
|
||||
// Utils.cpp
|
||||
|
||||
// Implements utility functions
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
eEntityType Type;
|
||||
const char * String;
|
||||
} g_EntityTypes[] =
|
||||
{
|
||||
{entBat, "Bat"},
|
||||
{entBlaze, "Blaze"},
|
||||
{entCaveSpider, "CaveSpider"},
|
||||
{entChicken, "Chicken"},
|
||||
{entCow, "Cow"},
|
||||
{entCreeper, "Creeper"},
|
||||
{entEnderDragon, "EnderDragon"},
|
||||
{entEnderman, "Enderman"},
|
||||
{entGhast, "Ghast"},
|
||||
{entGiant, "Giant"},
|
||||
{entLavaSlime, "LavaSlime"},
|
||||
{entMushroomCow, "MushroomCow"},
|
||||
{entOzelot, "Ozelot"},
|
||||
{entPig, "Pig"},
|
||||
{entPigZombie, "PigZombie"},
|
||||
{entSheep, "Sheep"},
|
||||
{entSilverfish, "Slverfish"},
|
||||
{entSkeleton, "Skeleton"},
|
||||
{entSlime, "Slime"},
|
||||
{entSnowMan, "SnowMan"},
|
||||
{entSpider, "Spider"},
|
||||
{entSquid, "Squid"},
|
||||
{entVillager, "Villager"},
|
||||
{entVillagerGolem, "VillagerGolem"},
|
||||
{entWitch, "Witch"},
|
||||
{entWitherBoss, "WitherBoss"},
|
||||
{entWolf, "Wolf"},
|
||||
{entZombie, "Zombie"},
|
||||
{entUnknown, "Unknown"},
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const char * GetBiomeString(unsigned char a_Biome)
|
||||
{
|
||||
static const char * BiomeNames[] = // Biome names, as equivalent to their index
|
||||
{
|
||||
"Ocean",
|
||||
"Plains",
|
||||
"Desert",
|
||||
"Extreme Hills",
|
||||
"Forest",
|
||||
"Taiga",
|
||||
"Swampland",
|
||||
"River",
|
||||
"Hell",
|
||||
"Sky",
|
||||
"Frozen Ocean",
|
||||
"Frozen River",
|
||||
"Ice Plains",
|
||||
"Ice Mountains",
|
||||
"Mushroom Island",
|
||||
"Mushroom Island Shore",
|
||||
"Beach",
|
||||
"Desert Hills",
|
||||
"Forest Hills",
|
||||
"Taiga Hills",
|
||||
"Extreme Hills Edge",
|
||||
"Jungle",
|
||||
"Jungle Hills",
|
||||
} ;
|
||||
return (a_Biome < ARRAYCOUNT(BiomeNames)) ? BiomeNames[a_Biome] : "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const char * GetBlockTypeString(unsigned char a_BlockType)
|
||||
{
|
||||
static const char * BlockTypeNames[] = // Block type names, as equivalent to their index
|
||||
{
|
||||
"air",
|
||||
"stone",
|
||||
"grass",
|
||||
"dirt",
|
||||
"cobblestone",
|
||||
"planks",
|
||||
"sapling",
|
||||
"bedrock",
|
||||
"water",
|
||||
"stillwater",
|
||||
"lava",
|
||||
"stilllava",
|
||||
"sand",
|
||||
"gravel",
|
||||
"goldore",
|
||||
"ironore",
|
||||
"coalore",
|
||||
"log",
|
||||
"leaves",
|
||||
"sponge",
|
||||
"glass",
|
||||
"lapisore",
|
||||
"lapisblock",
|
||||
"dispenser",
|
||||
"sandstone",
|
||||
"noteblock",
|
||||
"bedblock",
|
||||
"poweredrail",
|
||||
"detectorrail",
|
||||
"stickypiston",
|
||||
"cobweb",
|
||||
"tallgrass",
|
||||
"deadbush",
|
||||
"piston",
|
||||
"pistonhead",
|
||||
"wool",
|
||||
"pistonmovedblock",
|
||||
"flower",
|
||||
"rose",
|
||||
"brownmushroom",
|
||||
"redmushroom",
|
||||
"goldblock",
|
||||
"ironblock",
|
||||
"doubleslab",
|
||||
"slab",
|
||||
"brickblock",
|
||||
"tnt",
|
||||
"bookcase",
|
||||
"mossycobblestone",
|
||||
"obsidian",
|
||||
"torch",
|
||||
"fire",
|
||||
"mobspawner",
|
||||
"woodstairs",
|
||||
"chest",
|
||||
"redstonedust",
|
||||
"diamondore",
|
||||
"diamondblock",
|
||||
"workbench",
|
||||
"crops",
|
||||
"soil",
|
||||
"furnace",
|
||||
"litfurnace",
|
||||
"signblock",
|
||||
"wooddoorblock",
|
||||
"ladder",
|
||||
"tracks",
|
||||
"cobblestonestairs",
|
||||
"wallsign",
|
||||
"lever",
|
||||
"stoneplate",
|
||||
"irondoorblock",
|
||||
"woodplate",
|
||||
"redstoneore",
|
||||
"redstoneorealt",
|
||||
"redstonetorchoff",
|
||||
"redstonetorchon",
|
||||
"button",
|
||||
"snow",
|
||||
"ice",
|
||||
"snowblock",
|
||||
"cactus",
|
||||
"clayblock",
|
||||
"reedblock",
|
||||
"jukebox",
|
||||
"fence",
|
||||
"pumpkin",
|
||||
"netherrack",
|
||||
"soulsand",
|
||||
"glowstone",
|
||||
"portal",
|
||||
"jack-o-lantern",
|
||||
"cakeblock",
|
||||
"repeateroff",
|
||||
"repeateron",
|
||||
"lockedchest",
|
||||
"trapdoor",
|
||||
"silverfishblock",
|
||||
"stonebricks",
|
||||
"hugebrownmushroom",
|
||||
"hugeredmushroom",
|
||||
"ironbars",
|
||||
"glasspane",
|
||||
"melon",
|
||||
"pumpkinstem",
|
||||
"melonstem",
|
||||
"vines",
|
||||
"fencegate",
|
||||
"brickstairs",
|
||||
"stonebrickstairs",
|
||||
"mycelium",
|
||||
"lilypad",
|
||||
"netherbrick",
|
||||
"netherbrickfence",
|
||||
"netherbrickstairs",
|
||||
"netherwartblock",
|
||||
"enchantmenttable",
|
||||
"brewingstandblock",
|
||||
"cauldronblock",
|
||||
"endportal",
|
||||
"endportalframe",
|
||||
"endstone",
|
||||
"dragonegg",
|
||||
"redstonelampoff",
|
||||
"redstonelampon",
|
||||
"woodendoubleslab",
|
||||
"woodenslab",
|
||||
"cocoapod",
|
||||
"sandstonestairs", /* 128 */
|
||||
"Emerald Ore",
|
||||
"Ender Chest",
|
||||
"Tripwire Hook",
|
||||
"Tripwire",
|
||||
"Block of Emerald",
|
||||
"Spruce Wood Stairs",
|
||||
"Birch Wood Stairs",
|
||||
"Jungle Wood Stairs",
|
||||
"Command Block",
|
||||
"Beacon",
|
||||
"Cobblestone Wall",
|
||||
"Flower Pot",
|
||||
"Carrots",
|
||||
"Potatoes",
|
||||
"Wooden Button",
|
||||
"Head",
|
||||
} ;
|
||||
|
||||
return (a_BlockType < ARRAYCOUNT(BlockTypeNames)) ? BlockTypeNames[a_BlockType] : "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
eEntityType GetEntityType(const AString & a_EntityTypeString)
|
||||
{
|
||||
for (int i = 0; i < ARRAYCOUNT(g_EntityTypes); i++)
|
||||
{
|
||||
if (a_EntityTypeString == g_EntityTypes[i].String)
|
||||
{
|
||||
return g_EntityTypes[i].Type;
|
||||
}
|
||||
}
|
||||
return entUnknown;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern const char * GetEntityTypeString(eEntityType a_EntityType)
|
||||
{
|
||||
return g_EntityTypes[a_EntityType].String;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int GetNumCores(void)
|
||||
{
|
||||
// Get number of cores by querying the system process affinity mask (Windows-specific)
|
||||
DWORD Affinity, ProcAffinity;
|
||||
GetProcessAffinityMask(GetCurrentProcess(), &ProcAffinity, &Affinity);
|
||||
int NumCores = 0;
|
||||
while (Affinity > 0)
|
||||
{
|
||||
if ((Affinity & 1) == 1)
|
||||
{
|
||||
++NumCores;
|
||||
}
|
||||
Affinity >>= 1;
|
||||
} // while (Affinity > 0)
|
||||
return NumCores;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Utils.cpp
|
||||
|
||||
// Implements utility functions
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
eEntityType Type;
|
||||
const char * String;
|
||||
} g_EntityTypes[] =
|
||||
{
|
||||
{entBat, "Bat"},
|
||||
{entBlaze, "Blaze"},
|
||||
{entCaveSpider, "CaveSpider"},
|
||||
{entChicken, "Chicken"},
|
||||
{entCow, "Cow"},
|
||||
{entCreeper, "Creeper"},
|
||||
{entEnderDragon, "EnderDragon"},
|
||||
{entEnderman, "Enderman"},
|
||||
{entGhast, "Ghast"},
|
||||
{entGiant, "Giant"},
|
||||
{entLavaSlime, "LavaSlime"},
|
||||
{entMushroomCow, "MushroomCow"},
|
||||
{entOzelot, "Ozelot"},
|
||||
{entPig, "Pig"},
|
||||
{entPigZombie, "PigZombie"},
|
||||
{entSheep, "Sheep"},
|
||||
{entSilverfish, "Slverfish"},
|
||||
{entSkeleton, "Skeleton"},
|
||||
{entSlime, "Slime"},
|
||||
{entSnowMan, "SnowMan"},
|
||||
{entSpider, "Spider"},
|
||||
{entSquid, "Squid"},
|
||||
{entVillager, "Villager"},
|
||||
{entVillagerGolem, "VillagerGolem"},
|
||||
{entWitch, "Witch"},
|
||||
{entWitherBoss, "WitherBoss"},
|
||||
{entWolf, "Wolf"},
|
||||
{entZombie, "Zombie"},
|
||||
{entUnknown, "Unknown"},
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const char * GetBiomeString(unsigned char a_Biome)
|
||||
{
|
||||
static const char * BiomeNames[] = // Biome names, as equivalent to their index
|
||||
{
|
||||
"Ocean",
|
||||
"Plains",
|
||||
"Desert",
|
||||
"Extreme Hills",
|
||||
"Forest",
|
||||
"Taiga",
|
||||
"Swampland",
|
||||
"River",
|
||||
"Hell",
|
||||
"Sky",
|
||||
"Frozen Ocean",
|
||||
"Frozen River",
|
||||
"Ice Plains",
|
||||
"Ice Mountains",
|
||||
"Mushroom Island",
|
||||
"Mushroom Island Shore",
|
||||
"Beach",
|
||||
"Desert Hills",
|
||||
"Forest Hills",
|
||||
"Taiga Hills",
|
||||
"Extreme Hills Edge",
|
||||
"Jungle",
|
||||
"Jungle Hills",
|
||||
} ;
|
||||
return (a_Biome < ARRAYCOUNT(BiomeNames)) ? BiomeNames[a_Biome] : "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const char * GetBlockTypeString(unsigned char a_BlockType)
|
||||
{
|
||||
static const char * BlockTypeNames[] = // Block type names, as equivalent to their index
|
||||
{
|
||||
"air",
|
||||
"stone",
|
||||
"grass",
|
||||
"dirt",
|
||||
"cobblestone",
|
||||
"planks",
|
||||
"sapling",
|
||||
"bedrock",
|
||||
"water",
|
||||
"stillwater",
|
||||
"lava",
|
||||
"stilllava",
|
||||
"sand",
|
||||
"gravel",
|
||||
"goldore",
|
||||
"ironore",
|
||||
"coalore",
|
||||
"log",
|
||||
"leaves",
|
||||
"sponge",
|
||||
"glass",
|
||||
"lapisore",
|
||||
"lapisblock",
|
||||
"dispenser",
|
||||
"sandstone",
|
||||
"noteblock",
|
||||
"bedblock",
|
||||
"poweredrail",
|
||||
"detectorrail",
|
||||
"stickypiston",
|
||||
"cobweb",
|
||||
"tallgrass",
|
||||
"deadbush",
|
||||
"piston",
|
||||
"pistonhead",
|
||||
"wool",
|
||||
"pistonmovedblock",
|
||||
"flower",
|
||||
"rose",
|
||||
"brownmushroom",
|
||||
"redmushroom",
|
||||
"goldblock",
|
||||
"ironblock",
|
||||
"doubleslab",
|
||||
"slab",
|
||||
"brickblock",
|
||||
"tnt",
|
||||
"bookcase",
|
||||
"mossycobblestone",
|
||||
"obsidian",
|
||||
"torch",
|
||||
"fire",
|
||||
"mobspawner",
|
||||
"woodstairs",
|
||||
"chest",
|
||||
"redstonedust",
|
||||
"diamondore",
|
||||
"diamondblock",
|
||||
"workbench",
|
||||
"crops",
|
||||
"soil",
|
||||
"furnace",
|
||||
"litfurnace",
|
||||
"signblock",
|
||||
"wooddoorblock",
|
||||
"ladder",
|
||||
"tracks",
|
||||
"cobblestonestairs",
|
||||
"wallsign",
|
||||
"lever",
|
||||
"stoneplate",
|
||||
"irondoorblock",
|
||||
"woodplate",
|
||||
"redstoneore",
|
||||
"redstoneorealt",
|
||||
"redstonetorchoff",
|
||||
"redstonetorchon",
|
||||
"button",
|
||||
"snow",
|
||||
"ice",
|
||||
"snowblock",
|
||||
"cactus",
|
||||
"clayblock",
|
||||
"reedblock",
|
||||
"jukebox",
|
||||
"fence",
|
||||
"pumpkin",
|
||||
"netherrack",
|
||||
"soulsand",
|
||||
"glowstone",
|
||||
"portal",
|
||||
"jack-o-lantern",
|
||||
"cakeblock",
|
||||
"repeateroff",
|
||||
"repeateron",
|
||||
"lockedchest",
|
||||
"trapdoor",
|
||||
"silverfishblock",
|
||||
"stonebricks",
|
||||
"hugebrownmushroom",
|
||||
"hugeredmushroom",
|
||||
"ironbars",
|
||||
"glasspane",
|
||||
"melon",
|
||||
"pumpkinstem",
|
||||
"melonstem",
|
||||
"vines",
|
||||
"fencegate",
|
||||
"brickstairs",
|
||||
"stonebrickstairs",
|
||||
"mycelium",
|
||||
"lilypad",
|
||||
"netherbrick",
|
||||
"netherbrickfence",
|
||||
"netherbrickstairs",
|
||||
"netherwartblock",
|
||||
"enchantmenttable",
|
||||
"brewingstandblock",
|
||||
"cauldronblock",
|
||||
"endportal",
|
||||
"endportalframe",
|
||||
"endstone",
|
||||
"dragonegg",
|
||||
"redstonelampoff",
|
||||
"redstonelampon",
|
||||
"woodendoubleslab",
|
||||
"woodenslab",
|
||||
"cocoapod",
|
||||
"sandstonestairs", /* 128 */
|
||||
"Emerald Ore",
|
||||
"Ender Chest",
|
||||
"Tripwire Hook",
|
||||
"Tripwire",
|
||||
"Block of Emerald",
|
||||
"Spruce Wood Stairs",
|
||||
"Birch Wood Stairs",
|
||||
"Jungle Wood Stairs",
|
||||
"Command Block",
|
||||
"Beacon",
|
||||
"Cobblestone Wall",
|
||||
"Flower Pot",
|
||||
"Carrots",
|
||||
"Potatoes",
|
||||
"Wooden Button",
|
||||
"Head",
|
||||
} ;
|
||||
|
||||
return (a_BlockType < ARRAYCOUNT(BlockTypeNames)) ? BlockTypeNames[a_BlockType] : "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
eEntityType GetEntityType(const AString & a_EntityTypeString)
|
||||
{
|
||||
for (int i = 0; i < ARRAYCOUNT(g_EntityTypes); i++)
|
||||
{
|
||||
if (a_EntityTypeString == g_EntityTypes[i].String)
|
||||
{
|
||||
return g_EntityTypes[i].Type;
|
||||
}
|
||||
}
|
||||
return entUnknown;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern const char * GetEntityTypeString(eEntityType a_EntityType)
|
||||
{
|
||||
return g_EntityTypes[a_EntityType].String;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int GetNumCores(void)
|
||||
{
|
||||
// Get number of cores by querying the system process affinity mask (Windows-specific)
|
||||
DWORD Affinity, ProcAffinity;
|
||||
GetProcessAffinityMask(GetCurrentProcess(), &ProcAffinity, &Affinity);
|
||||
int NumCores = 0;
|
||||
while (Affinity > 0)
|
||||
{
|
||||
if ((Affinity & 1) == 1)
|
||||
{
|
||||
++NumCores;
|
||||
}
|
||||
Affinity >>= 1;
|
||||
} // while (Affinity > 0)
|
||||
return NumCores;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,61 +1,61 @@
|
||||
|
||||
// Utils.h
|
||||
|
||||
// Interfaces to utility functions
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum eEntityType
|
||||
{
|
||||
entBat,
|
||||
entBlaze,
|
||||
entCaveSpider,
|
||||
entChicken,
|
||||
entCow,
|
||||
entCreeper,
|
||||
entEnderDragon,
|
||||
entEnderman,
|
||||
entGhast,
|
||||
entGiant,
|
||||
entLavaSlime,
|
||||
entMushroomCow,
|
||||
entOzelot,
|
||||
entPig,
|
||||
entPigZombie,
|
||||
entSheep,
|
||||
entSilverfish,
|
||||
entSkeleton,
|
||||
entSlime,
|
||||
entSnowMan,
|
||||
entSpider,
|
||||
entSquid,
|
||||
entVillager,
|
||||
entVillagerGolem,
|
||||
entWitch,
|
||||
entWitherBoss,
|
||||
entWolf,
|
||||
entZombie,
|
||||
entUnknown,
|
||||
entMax = entUnknown,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern const char * GetBiomeString(unsigned char a_Biome);
|
||||
extern const char * GetBlockTypeString(unsigned char a_BlockType);
|
||||
extern eEntityType GetEntityType(const AString & a_EntityTypeString);
|
||||
extern const char * GetEntityTypeString(eEntityType a_EntityType);
|
||||
extern int GetNumCores(void);
|
||||
|
||||
|
||||
|
||||
|
||||
// Utils.h
|
||||
|
||||
// Interfaces to utility functions
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum eEntityType
|
||||
{
|
||||
entBat,
|
||||
entBlaze,
|
||||
entCaveSpider,
|
||||
entChicken,
|
||||
entCow,
|
||||
entCreeper,
|
||||
entEnderDragon,
|
||||
entEnderman,
|
||||
entGhast,
|
||||
entGiant,
|
||||
entLavaSlime,
|
||||
entMushroomCow,
|
||||
entOzelot,
|
||||
entPig,
|
||||
entPigZombie,
|
||||
entSheep,
|
||||
entSilverfish,
|
||||
entSkeleton,
|
||||
entSlime,
|
||||
entSnowMan,
|
||||
entSpider,
|
||||
entSquid,
|
||||
entVillager,
|
||||
entVillagerGolem,
|
||||
entWitch,
|
||||
entWitherBoss,
|
||||
entWolf,
|
||||
entZombie,
|
||||
entUnknown,
|
||||
entMax = entUnknown,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern const char * GetBiomeString(unsigned char a_Biome);
|
||||
extern const char * GetBlockTypeString(unsigned char a_BlockType);
|
||||
extern eEntityType GetEntityType(const AString & a_EntityTypeString);
|
||||
extern const char * GetEntityTypeString(eEntityType a_EntityType);
|
||||
extern int GetNumCores(void);
|
||||
|
||||
|
||||
|
||||
|
@ -1,70 +1,70 @@
|
||||
@echo off
|
||||
::
|
||||
:: Profiling using a MSVC standalone profiler
|
||||
::
|
||||
:: See http://www.codeproject.com/Articles/144643/Profiling-of-C-Applications-in-Visual-Studio-for-F for details
|
||||
::
|
||||
|
||||
|
||||
|
||||
|
||||
set pt="C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools"
|
||||
set appdir="Release profiled"
|
||||
set app="Release profiled\AnvilStats.exe"
|
||||
set args="0 c:\Games\MLG\world\region"
|
||||
|
||||
:: outputdir is relative to appdir!
|
||||
set outputdir=Profiling
|
||||
set output=profile.vsp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
::Create the output directory, if it didn't exist
|
||||
mkdir %outputdir%
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Start the profiler
|
||||
%pt%\vsperfcmd /start:sample /output:%outputdir%\%output%
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
:: Launch the application via the profiler
|
||||
%pt%\vsperfcmd /launch:%app% /args:%args%
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
:: Shut down the profiler (this command waits, until the application is terminated)
|
||||
%pt%\vsperfcmd /shutdown
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: cd to outputdir, so that the reports are generated there
|
||||
cd %outputdir%
|
||||
|
||||
:: generate the report files (.csv)
|
||||
%pt%\vsperfreport /summary:all %output% /symbolpath:"srv*C:\Programovani\Symbols*http://msdl.microsoft.com/download/symbols"
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
goto finished
|
||||
|
||||
|
||||
|
||||
|
||||
:haderror
|
||||
echo An error was encountered
|
||||
pause
|
||||
|
||||
|
||||
|
||||
|
||||
:finished
|
||||
@echo off
|
||||
::
|
||||
:: Profiling using a MSVC standalone profiler
|
||||
::
|
||||
:: See http://www.codeproject.com/Articles/144643/Profiling-of-C-Applications-in-Visual-Studio-for-F for details
|
||||
::
|
||||
|
||||
|
||||
|
||||
|
||||
set pt="C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools"
|
||||
set appdir="Release profiled"
|
||||
set app="Release profiled\AnvilStats.exe"
|
||||
set args="0 c:\Games\MLG\world\region"
|
||||
|
||||
:: outputdir is relative to appdir!
|
||||
set outputdir=Profiling
|
||||
set output=profile.vsp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
::Create the output directory, if it didn't exist
|
||||
mkdir %outputdir%
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Start the profiler
|
||||
%pt%\vsperfcmd /start:sample /output:%outputdir%\%output%
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
:: Launch the application via the profiler
|
||||
%pt%\vsperfcmd /launch:%app% /args:%args%
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
:: Shut down the profiler (this command waits, until the application is terminated)
|
||||
%pt%\vsperfcmd /shutdown
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: cd to outputdir, so that the reports are generated there
|
||||
cd %outputdir%
|
||||
|
||||
:: generate the report files (.csv)
|
||||
%pt%\vsperfreport /summary:all %output% /symbolpath:"srv*C:\Programovani\Symbols*http://msdl.microsoft.com/download/symbols"
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
goto finished
|
||||
|
||||
|
||||
|
||||
|
||||
:haderror
|
||||
echo An error was encountered
|
||||
pause
|
||||
|
||||
|
||||
|
||||
|
||||
:finished
|
||||
|
@ -1,333 +1,333 @@
|
||||
|
||||
// BiomeCache.cpp
|
||||
|
||||
// Implements the cBiomeCache class representing a biome source that caches data from the underlying biome source
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "Timer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int GetNumCores(void)
|
||||
{
|
||||
// Get number of cores by querying the system process affinity mask
|
||||
DWORD Affinity, ProcAffinity;
|
||||
GetProcessAffinityMask(GetCurrentProcess(), &ProcAffinity, &Affinity);
|
||||
int NumCores = 0;
|
||||
while (Affinity > 0)
|
||||
{
|
||||
if ((Affinity & 1) == 1)
|
||||
{
|
||||
NumCores++;
|
||||
}
|
||||
Affinity >>= 1;
|
||||
} // while (Affinity > 0)
|
||||
return NumCores;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeCache::cBiomeCache(void) :
|
||||
m_Source(NULL),
|
||||
m_BaseX(-100000),
|
||||
m_BaseZ(-100000),
|
||||
m_Available(NULL),
|
||||
m_IsTerminatingThreads(false)
|
||||
{
|
||||
int NumThreads = GetNumCores();
|
||||
NumThreads--; // One core should be left for the system to run on ;)
|
||||
for (int i = NumThreads; i > 0; i--)
|
||||
{
|
||||
cThread * Thread = new cThread(*this);
|
||||
m_Threads.push_back(Thread);
|
||||
Thread->Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeCache::~cBiomeCache()
|
||||
{
|
||||
m_IsTerminatingThreads = true;
|
||||
for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr)
|
||||
{
|
||||
m_evtQueued.Set();
|
||||
}
|
||||
for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr)
|
||||
{
|
||||
delete *itr;
|
||||
}
|
||||
m_Threads.clear();
|
||||
|
||||
SetSource(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeSource::eAvailability cBiomeCache::GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes)
|
||||
{
|
||||
if (m_Source == NULL)
|
||||
{
|
||||
return baNever;
|
||||
}
|
||||
|
||||
// Look up using the cache:
|
||||
int x = a_ChunkX - m_BaseX;
|
||||
int z = a_ChunkZ - m_BaseZ;
|
||||
if ((x < 0) || (x >= m_Width) || (z < 0) || (z >= m_Height))
|
||||
{
|
||||
// Outside the cached region
|
||||
return baNever;
|
||||
}
|
||||
|
||||
cCSLock Lock(m_CS);
|
||||
cItem * Item = m_Available[x + m_Width * z];
|
||||
if (Item == NULL)
|
||||
{
|
||||
// Item hasn't been processed yet
|
||||
return baLater;
|
||||
}
|
||||
if (Item->m_IsValid)
|
||||
{
|
||||
memcpy(a_Biomes, Item->m_Biomes, sizeof(a_Biomes));
|
||||
return baNow;
|
||||
}
|
||||
|
||||
// Item has been processed, but the underlying source refused to give the data to us
|
||||
return baNever;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ)
|
||||
{
|
||||
cTimer Timer("Cache: HintViewArea");
|
||||
|
||||
if (
|
||||
(a_MinChunkX == m_BaseX) &&
|
||||
(a_MaxChunkX == m_BaseX + m_Width - 1) &&
|
||||
(a_MinChunkZ == m_BaseZ) &&
|
||||
(a_MaxChunkZ == m_BaseZ + m_Height - 1)
|
||||
)
|
||||
{
|
||||
// The same set of parameters, bail out
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Source != NULL)
|
||||
{
|
||||
m_Source->HintViewArea(a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ);
|
||||
}
|
||||
|
||||
int NewWidth = a_MaxChunkX - a_MinChunkX + 1;
|
||||
int NewHeight = a_MaxChunkZ - a_MinChunkZ + 1;
|
||||
|
||||
// Make a new empty cache table:
|
||||
pItem * NewAvailable = new pItem[NewWidth * NewHeight];
|
||||
for (int i = NewWidth * NewHeight - 1; i >= 0; --i)
|
||||
{
|
||||
NewAvailable[i] = NULL;
|
||||
}
|
||||
|
||||
// Move the common contents of the old table into the new table:
|
||||
cCSLock Lock(m_CS);
|
||||
for (int z = 0; z < NewHeight; z++)
|
||||
{
|
||||
int OldZ = z + a_MinChunkZ - m_BaseZ;
|
||||
if ((OldZ < 0) || (OldZ >= m_Height))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (int x = 0; x < NewWidth; x++)
|
||||
{
|
||||
int OldX = x + a_MinChunkX - m_BaseX;
|
||||
if ((OldX < 0) || (OldX >= m_Width))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
NewAvailable[x + NewWidth * z] = m_Available[OldX + m_Width * OldZ];
|
||||
m_Available[OldX + m_Width * OldZ] = NULL;
|
||||
} // for x
|
||||
} // for z
|
||||
|
||||
// All items that aren't common go into the pool:
|
||||
for (int idx = 0, z = 0; z < m_Height; z++)
|
||||
{
|
||||
for (int x = 0; x < m_Width; ++x, ++idx)
|
||||
{
|
||||
if (m_Available[idx] != NULL)
|
||||
{
|
||||
m_Pool.push_back(m_Available[idx]);
|
||||
m_Available[idx] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the cache table:
|
||||
delete m_Available;
|
||||
m_Available = NewAvailable;
|
||||
m_Width = NewWidth;
|
||||
m_Height = NewHeight;
|
||||
m_BaseX = a_MinChunkX;
|
||||
m_BaseZ = a_MinChunkZ;
|
||||
|
||||
// Remove all items outside the coords:
|
||||
FilterOutItems(m_Queue, a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ);
|
||||
|
||||
// Queue all items from inside the coords into m_Queue:
|
||||
for (int z = 0; z < NewHeight; z++)
|
||||
{
|
||||
for (int x = 0; x < NewWidth; x++)
|
||||
{
|
||||
if (m_Available[x + m_Width * z] != NULL)
|
||||
{
|
||||
// Already calculated, skip
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_Pool.empty())
|
||||
{
|
||||
m_Pool.push_back(new cItem(x + a_MinChunkX, z + a_MinChunkZ));
|
||||
}
|
||||
ASSERT(!m_Pool.empty());
|
||||
m_Pool.back()->m_ChunkX = x + a_MinChunkX;
|
||||
m_Pool.back()->m_ChunkZ = z + a_MinChunkZ;
|
||||
m_Queue.push_back(m_Pool.back());
|
||||
m_Pool.pop_back();
|
||||
m_evtQueued.Set();
|
||||
} // for x
|
||||
} // for z
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::SetSource(cBiomeSource * a_Source)
|
||||
{
|
||||
// TODO: Stop all threads, so that they don't use the source anymore!
|
||||
|
||||
delete m_Source;
|
||||
m_Source = a_Source;
|
||||
|
||||
// Invalidate cache contents:
|
||||
cCSLock Lock(m_CS);
|
||||
m_BaseX = -10000;
|
||||
m_BaseZ = -10000;
|
||||
m_Pool.splice(m_Pool.end(), m_Queue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ)
|
||||
{
|
||||
for (cItems::iterator itr = a_Items.begin(); itr != a_Items.end();)
|
||||
{
|
||||
if (
|
||||
((*itr)->m_ChunkX < a_MinChunkX) ||
|
||||
((*itr)->m_ChunkX > a_MaxChunkX) ||
|
||||
((*itr)->m_ChunkX < a_MinChunkX) ||
|
||||
((*itr)->m_ChunkX > a_MaxChunkX)
|
||||
)
|
||||
{
|
||||
m_Pool.push_back(*itr);
|
||||
itr = a_Items.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::thrProcessQueueItem(void)
|
||||
{
|
||||
cItem * Item = NULL;
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
if (m_Queue.empty())
|
||||
{
|
||||
cCSUnlock Unlock(Lock);
|
||||
m_evtQueued.Wait();
|
||||
}
|
||||
if (m_IsTerminatingThreads || m_Queue.empty())
|
||||
{
|
||||
// We've been woken up only to die / spurious wakeup
|
||||
return;
|
||||
}
|
||||
Item = m_Queue.back();
|
||||
m_Queue.pop_back();
|
||||
}
|
||||
|
||||
// Process the item:
|
||||
Item->m_IsValid = (m_Source->GetBiome(Item->m_ChunkX, Item->m_ChunkZ, Item->m_Biomes) == baNow);
|
||||
|
||||
// Store result:
|
||||
cCSLock Lock(m_CS);
|
||||
int x = Item->m_ChunkX - m_BaseX;
|
||||
int z = Item->m_ChunkZ - m_BaseZ;
|
||||
if ((x < 0) || (x >= m_Width) || (z < 0) || (z >= m_Height))
|
||||
{
|
||||
// The cache rectangle has changed under our fingers, drop this chunk
|
||||
return;
|
||||
}
|
||||
m_Available[x + m_Width * z] = Item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeCache::cItem:
|
||||
|
||||
cBiomeCache::cItem::cItem(int a_ChunkX, int a_ChunkZ) :
|
||||
m_ChunkX(a_ChunkX),
|
||||
m_ChunkZ(a_ChunkZ)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeCache::cThread:
|
||||
|
||||
cBiomeCache::cThread::cThread(cBiomeCache & a_Parent) :
|
||||
super("Biome cache thread"),
|
||||
m_Parent(a_Parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::cThread::Execute(void)
|
||||
{
|
||||
while (!m_ShouldTerminate && !m_Parent.m_IsTerminatingThreads)
|
||||
{
|
||||
m_Parent.thrProcessQueueItem();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// BiomeCache.cpp
|
||||
|
||||
// Implements the cBiomeCache class representing a biome source that caches data from the underlying biome source
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "Timer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int GetNumCores(void)
|
||||
{
|
||||
// Get number of cores by querying the system process affinity mask
|
||||
DWORD Affinity, ProcAffinity;
|
||||
GetProcessAffinityMask(GetCurrentProcess(), &ProcAffinity, &Affinity);
|
||||
int NumCores = 0;
|
||||
while (Affinity > 0)
|
||||
{
|
||||
if ((Affinity & 1) == 1)
|
||||
{
|
||||
NumCores++;
|
||||
}
|
||||
Affinity >>= 1;
|
||||
} // while (Affinity > 0)
|
||||
return NumCores;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeCache::cBiomeCache(void) :
|
||||
m_Source(NULL),
|
||||
m_BaseX(-100000),
|
||||
m_BaseZ(-100000),
|
||||
m_Available(NULL),
|
||||
m_IsTerminatingThreads(false)
|
||||
{
|
||||
int NumThreads = GetNumCores();
|
||||
NumThreads--; // One core should be left for the system to run on ;)
|
||||
for (int i = NumThreads; i > 0; i--)
|
||||
{
|
||||
cThread * Thread = new cThread(*this);
|
||||
m_Threads.push_back(Thread);
|
||||
Thread->Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeCache::~cBiomeCache()
|
||||
{
|
||||
m_IsTerminatingThreads = true;
|
||||
for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr)
|
||||
{
|
||||
m_evtQueued.Set();
|
||||
}
|
||||
for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr)
|
||||
{
|
||||
delete *itr;
|
||||
}
|
||||
m_Threads.clear();
|
||||
|
||||
SetSource(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeSource::eAvailability cBiomeCache::GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes)
|
||||
{
|
||||
if (m_Source == NULL)
|
||||
{
|
||||
return baNever;
|
||||
}
|
||||
|
||||
// Look up using the cache:
|
||||
int x = a_ChunkX - m_BaseX;
|
||||
int z = a_ChunkZ - m_BaseZ;
|
||||
if ((x < 0) || (x >= m_Width) || (z < 0) || (z >= m_Height))
|
||||
{
|
||||
// Outside the cached region
|
||||
return baNever;
|
||||
}
|
||||
|
||||
cCSLock Lock(m_CS);
|
||||
cItem * Item = m_Available[x + m_Width * z];
|
||||
if (Item == NULL)
|
||||
{
|
||||
// Item hasn't been processed yet
|
||||
return baLater;
|
||||
}
|
||||
if (Item->m_IsValid)
|
||||
{
|
||||
memcpy(a_Biomes, Item->m_Biomes, sizeof(a_Biomes));
|
||||
return baNow;
|
||||
}
|
||||
|
||||
// Item has been processed, but the underlying source refused to give the data to us
|
||||
return baNever;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ)
|
||||
{
|
||||
cTimer Timer("Cache: HintViewArea");
|
||||
|
||||
if (
|
||||
(a_MinChunkX == m_BaseX) &&
|
||||
(a_MaxChunkX == m_BaseX + m_Width - 1) &&
|
||||
(a_MinChunkZ == m_BaseZ) &&
|
||||
(a_MaxChunkZ == m_BaseZ + m_Height - 1)
|
||||
)
|
||||
{
|
||||
// The same set of parameters, bail out
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Source != NULL)
|
||||
{
|
||||
m_Source->HintViewArea(a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ);
|
||||
}
|
||||
|
||||
int NewWidth = a_MaxChunkX - a_MinChunkX + 1;
|
||||
int NewHeight = a_MaxChunkZ - a_MinChunkZ + 1;
|
||||
|
||||
// Make a new empty cache table:
|
||||
pItem * NewAvailable = new pItem[NewWidth * NewHeight];
|
||||
for (int i = NewWidth * NewHeight - 1; i >= 0; --i)
|
||||
{
|
||||
NewAvailable[i] = NULL;
|
||||
}
|
||||
|
||||
// Move the common contents of the old table into the new table:
|
||||
cCSLock Lock(m_CS);
|
||||
for (int z = 0; z < NewHeight; z++)
|
||||
{
|
||||
int OldZ = z + a_MinChunkZ - m_BaseZ;
|
||||
if ((OldZ < 0) || (OldZ >= m_Height))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (int x = 0; x < NewWidth; x++)
|
||||
{
|
||||
int OldX = x + a_MinChunkX - m_BaseX;
|
||||
if ((OldX < 0) || (OldX >= m_Width))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
NewAvailable[x + NewWidth * z] = m_Available[OldX + m_Width * OldZ];
|
||||
m_Available[OldX + m_Width * OldZ] = NULL;
|
||||
} // for x
|
||||
} // for z
|
||||
|
||||
// All items that aren't common go into the pool:
|
||||
for (int idx = 0, z = 0; z < m_Height; z++)
|
||||
{
|
||||
for (int x = 0; x < m_Width; ++x, ++idx)
|
||||
{
|
||||
if (m_Available[idx] != NULL)
|
||||
{
|
||||
m_Pool.push_back(m_Available[idx]);
|
||||
m_Available[idx] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the cache table:
|
||||
delete m_Available;
|
||||
m_Available = NewAvailable;
|
||||
m_Width = NewWidth;
|
||||
m_Height = NewHeight;
|
||||
m_BaseX = a_MinChunkX;
|
||||
m_BaseZ = a_MinChunkZ;
|
||||
|
||||
// Remove all items outside the coords:
|
||||
FilterOutItems(m_Queue, a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ);
|
||||
|
||||
// Queue all items from inside the coords into m_Queue:
|
||||
for (int z = 0; z < NewHeight; z++)
|
||||
{
|
||||
for (int x = 0; x < NewWidth; x++)
|
||||
{
|
||||
if (m_Available[x + m_Width * z] != NULL)
|
||||
{
|
||||
// Already calculated, skip
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_Pool.empty())
|
||||
{
|
||||
m_Pool.push_back(new cItem(x + a_MinChunkX, z + a_MinChunkZ));
|
||||
}
|
||||
ASSERT(!m_Pool.empty());
|
||||
m_Pool.back()->m_ChunkX = x + a_MinChunkX;
|
||||
m_Pool.back()->m_ChunkZ = z + a_MinChunkZ;
|
||||
m_Queue.push_back(m_Pool.back());
|
||||
m_Pool.pop_back();
|
||||
m_evtQueued.Set();
|
||||
} // for x
|
||||
} // for z
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::SetSource(cBiomeSource * a_Source)
|
||||
{
|
||||
// TODO: Stop all threads, so that they don't use the source anymore!
|
||||
|
||||
delete m_Source;
|
||||
m_Source = a_Source;
|
||||
|
||||
// Invalidate cache contents:
|
||||
cCSLock Lock(m_CS);
|
||||
m_BaseX = -10000;
|
||||
m_BaseZ = -10000;
|
||||
m_Pool.splice(m_Pool.end(), m_Queue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ)
|
||||
{
|
||||
for (cItems::iterator itr = a_Items.begin(); itr != a_Items.end();)
|
||||
{
|
||||
if (
|
||||
((*itr)->m_ChunkX < a_MinChunkX) ||
|
||||
((*itr)->m_ChunkX > a_MaxChunkX) ||
|
||||
((*itr)->m_ChunkX < a_MinChunkX) ||
|
||||
((*itr)->m_ChunkX > a_MaxChunkX)
|
||||
)
|
||||
{
|
||||
m_Pool.push_back(*itr);
|
||||
itr = a_Items.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::thrProcessQueueItem(void)
|
||||
{
|
||||
cItem * Item = NULL;
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
if (m_Queue.empty())
|
||||
{
|
||||
cCSUnlock Unlock(Lock);
|
||||
m_evtQueued.Wait();
|
||||
}
|
||||
if (m_IsTerminatingThreads || m_Queue.empty())
|
||||
{
|
||||
// We've been woken up only to die / spurious wakeup
|
||||
return;
|
||||
}
|
||||
Item = m_Queue.back();
|
||||
m_Queue.pop_back();
|
||||
}
|
||||
|
||||
// Process the item:
|
||||
Item->m_IsValid = (m_Source->GetBiome(Item->m_ChunkX, Item->m_ChunkZ, Item->m_Biomes) == baNow);
|
||||
|
||||
// Store result:
|
||||
cCSLock Lock(m_CS);
|
||||
int x = Item->m_ChunkX - m_BaseX;
|
||||
int z = Item->m_ChunkZ - m_BaseZ;
|
||||
if ((x < 0) || (x >= m_Width) || (z < 0) || (z >= m_Height))
|
||||
{
|
||||
// The cache rectangle has changed under our fingers, drop this chunk
|
||||
return;
|
||||
}
|
||||
m_Available[x + m_Width * z] = Item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeCache::cItem:
|
||||
|
||||
cBiomeCache::cItem::cItem(int a_ChunkX, int a_ChunkZ) :
|
||||
m_ChunkX(a_ChunkX),
|
||||
m_ChunkZ(a_ChunkZ)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeCache::cThread:
|
||||
|
||||
cBiomeCache::cThread::cThread(cBiomeCache & a_Parent) :
|
||||
super("Biome cache thread"),
|
||||
m_Parent(a_Parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::cThread::Execute(void)
|
||||
{
|
||||
while (!m_ShouldTerminate && !m_Parent.m_IsTerminatingThreads)
|
||||
{
|
||||
m_Parent.thrProcessQueueItem();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,96 +1,96 @@
|
||||
|
||||
// BiomeCache.h
|
||||
|
||||
// Declares the cBiomeCache class representing a biome source that caches data from the underlying biome source
|
||||
|
||||
/*
|
||||
This cache works a bit differently than regular caches.
|
||||
It first receives the hint of area that it will need to provide.
|
||||
The Cache uses several threads to request biomes from the underlying source to fill that area.
|
||||
While the area is being filled, requests for biomes may already come, such requests are answered with baLater if no data yet.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "BiomeSource.h"
|
||||
#include "../source/OSSupport/IsThread.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeCache :
|
||||
public cBiomeSource
|
||||
{
|
||||
public:
|
||||
cBiomeCache(void);
|
||||
~cBiomeCache();
|
||||
|
||||
// cBiomeSource overrides:
|
||||
virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) override;
|
||||
virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) override;
|
||||
|
||||
void SetSource(cBiomeSource * a_Source); // Takes ownership of the source ptr
|
||||
|
||||
protected:
|
||||
class cItem
|
||||
{
|
||||
public:
|
||||
cItem(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
int m_ChunkX;
|
||||
int m_ChunkZ;
|
||||
bool m_IsValid;
|
||||
cChunkDef::BiomeMap m_Biomes;
|
||||
} ;
|
||||
|
||||
typedef cItem * pItem;
|
||||
typedef std::list<pItem> cItems;
|
||||
|
||||
class cThread :
|
||||
public cIsThread
|
||||
{
|
||||
typedef cIsThread super;
|
||||
|
||||
public:
|
||||
cThread(cBiomeCache & a_Parent);
|
||||
|
||||
// cIsThread overrides:
|
||||
virtual void Execute(void) override;
|
||||
|
||||
protected:
|
||||
cBiomeCache & m_Parent;
|
||||
} ;
|
||||
|
||||
typedef std::list<cThread *> cThreads;
|
||||
|
||||
cBiomeSource * m_Source;
|
||||
|
||||
cCriticalSection m_CS;
|
||||
int m_BaseX; ///< MinChunkX for the m_Available rectangle
|
||||
int m_BaseZ; ///< MinChunkZ for the m_Available rectangle
|
||||
int m_Width; ///< Width of the m_Available rectangle
|
||||
int m_Height; ///< Height of the m_Available rectangle
|
||||
pItem * m_Available; ///< Items that have already been processed (baNow or baNever), [x + m_Width * z]
|
||||
cItems m_Queue; ///< Items that are queued for processing (baLater)
|
||||
cItems m_Pool; ///< Items that are not needed anymore, can be reused for other coords
|
||||
|
||||
cEvent m_evtQueued; // Triggerred when an item is added to m_Queue
|
||||
|
||||
cThreads m_Threads; // Threads that update the cache.
|
||||
bool m_IsTerminatingThreads; // Set to true to indicate to all threads that they should exit
|
||||
|
||||
/// Removes from a_Items all items that are outside of the given coords, moves those into m_Pool
|
||||
void FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ);
|
||||
|
||||
/// Processes one item from m_Queue into m_Available. Blocks if m_Queue is empty; respects m_IsTerminatingThreads
|
||||
void thrProcessQueueItem(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// BiomeCache.h
|
||||
|
||||
// Declares the cBiomeCache class representing a biome source that caches data from the underlying biome source
|
||||
|
||||
/*
|
||||
This cache works a bit differently than regular caches.
|
||||
It first receives the hint of area that it will need to provide.
|
||||
The Cache uses several threads to request biomes from the underlying source to fill that area.
|
||||
While the area is being filled, requests for biomes may already come, such requests are answered with baLater if no data yet.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "BiomeSource.h"
|
||||
#include "../source/OSSupport/IsThread.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeCache :
|
||||
public cBiomeSource
|
||||
{
|
||||
public:
|
||||
cBiomeCache(void);
|
||||
~cBiomeCache();
|
||||
|
||||
// cBiomeSource overrides:
|
||||
virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) override;
|
||||
virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) override;
|
||||
|
||||
void SetSource(cBiomeSource * a_Source); // Takes ownership of the source ptr
|
||||
|
||||
protected:
|
||||
class cItem
|
||||
{
|
||||
public:
|
||||
cItem(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
int m_ChunkX;
|
||||
int m_ChunkZ;
|
||||
bool m_IsValid;
|
||||
cChunkDef::BiomeMap m_Biomes;
|
||||
} ;
|
||||
|
||||
typedef cItem * pItem;
|
||||
typedef std::list<pItem> cItems;
|
||||
|
||||
class cThread :
|
||||
public cIsThread
|
||||
{
|
||||
typedef cIsThread super;
|
||||
|
||||
public:
|
||||
cThread(cBiomeCache & a_Parent);
|
||||
|
||||
// cIsThread overrides:
|
||||
virtual void Execute(void) override;
|
||||
|
||||
protected:
|
||||
cBiomeCache & m_Parent;
|
||||
} ;
|
||||
|
||||
typedef std::list<cThread *> cThreads;
|
||||
|
||||
cBiomeSource * m_Source;
|
||||
|
||||
cCriticalSection m_CS;
|
||||
int m_BaseX; ///< MinChunkX for the m_Available rectangle
|
||||
int m_BaseZ; ///< MinChunkZ for the m_Available rectangle
|
||||
int m_Width; ///< Width of the m_Available rectangle
|
||||
int m_Height; ///< Height of the m_Available rectangle
|
||||
pItem * m_Available; ///< Items that have already been processed (baNow or baNever), [x + m_Width * z]
|
||||
cItems m_Queue; ///< Items that are queued for processing (baLater)
|
||||
cItems m_Pool; ///< Items that are not needed anymore, can be reused for other coords
|
||||
|
||||
cEvent m_evtQueued; // Triggerred when an item is added to m_Queue
|
||||
|
||||
cThreads m_Threads; // Threads that update the cache.
|
||||
bool m_IsTerminatingThreads; // Set to true to indicate to all threads that they should exit
|
||||
|
||||
/// Removes from a_Items all items that are outside of the given coords, moves those into m_Pool
|
||||
void FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ);
|
||||
|
||||
/// Processes one item from m_Queue into m_Available. Blocks if m_Queue is empty; respects m_IsTerminatingThreads
|
||||
void thrProcessQueueItem(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,147 +1,147 @@
|
||||
|
||||
// BiomeRenderer.cpp
|
||||
|
||||
// Implements the cBiomeRenderer class representing the rendering engine
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeRenderer.h"
|
||||
#include "Pixmap.h"
|
||||
#include "Timer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeRenderer::cBiomeRenderer(void) :
|
||||
m_OriginX(160),
|
||||
m_OriginY(160),
|
||||
m_Zoom(1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeRenderer::SetSource(cBiomeSource * a_Source)
|
||||
{
|
||||
m_Cache.SetSource(a_Source);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeRenderer::Render(cPixmap & a_Pixmap)
|
||||
{
|
||||
cTimer Timer("cBiomeRenderer::Render");
|
||||
|
||||
int Wid = a_Pixmap.GetWidth();
|
||||
int Hei = a_Pixmap.GetHeight();
|
||||
|
||||
// Hint the approximate view area to the biome source so that it can adjust its caches:
|
||||
int MinBlockX = ( - m_OriginX) / m_Zoom;
|
||||
int MaxBlockX = (Wid - m_OriginX) / m_Zoom;
|
||||
int MinBlockZ = ( - m_OriginY) / m_Zoom;
|
||||
int MaxBlockZ = (Hei - m_OriginY) / m_Zoom;
|
||||
m_Cache.HintViewArea(MinBlockX / 16 - 1, MaxBlockX / 16 + 1, MinBlockZ / 16 - 1, MaxBlockZ / 16 + 1);
|
||||
|
||||
// Hold one current chunk of biome data:
|
||||
int CurChunkX = -10000;
|
||||
int CurChunkZ = -10000;
|
||||
cChunkDef::BiomeMap CurBiomes;
|
||||
|
||||
bool res = false;
|
||||
|
||||
for (int y = 0; y < Hei; y++)
|
||||
{
|
||||
int BlockZ = (y - m_OriginY) / m_Zoom;
|
||||
int ChunkZ = (BlockZ >= 0) ? (BlockZ / 16) : ((BlockZ + 1) / 16 - 1);
|
||||
int RelZ = BlockZ - ChunkZ * 16;
|
||||
for (int x = 0; x < Wid; x++)
|
||||
{
|
||||
int BlockX = (x - m_OriginX) / m_Zoom;
|
||||
int ChunkX = (BlockX >= 0) ? (BlockX / 16) : ((BlockX + 1) / 16 - 1);
|
||||
int RelX = BlockX - ChunkX * 16;
|
||||
if ((ChunkZ != CurChunkZ) || (ChunkX != CurChunkX))
|
||||
{
|
||||
CurChunkX = ChunkX;
|
||||
CurChunkZ = ChunkZ;
|
||||
switch (m_Cache.GetBiome(CurChunkX, CurChunkZ, CurBiomes))
|
||||
{
|
||||
case cBiomeSource::baLater:
|
||||
{
|
||||
res = true;
|
||||
// fallthrough:
|
||||
}
|
||||
case cBiomeSource::baNever:
|
||||
{
|
||||
for (int i = 0; i < ARRAYCOUNT(CurBiomes); i++)
|
||||
{
|
||||
CurBiomes[i] = (EMCSBiome)-1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // switch (Biome availability)
|
||||
}
|
||||
EMCSBiome Biome = cChunkDef::GetBiome(CurBiomes, RelX, RelZ);
|
||||
a_Pixmap.SetPixel(x, y, GetBiomeColor(Biome));
|
||||
} // for x
|
||||
} // for y
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cBiomeRenderer::GetBiomeColor(EMCSBiome a_Biome)
|
||||
{
|
||||
if ((a_Biome < 0) || (a_Biome > biMaxBiome))
|
||||
{
|
||||
return 0xcfcfcf; // LtGray for unknown biomes
|
||||
}
|
||||
|
||||
static int BiomeColor[] =
|
||||
{
|
||||
// RGB:
|
||||
0x0000ff, /* Ocean */
|
||||
0x00cf3f, /* Plains */
|
||||
0xffff00, /* Desert */
|
||||
0x7f7f7f, /* Extreme Hills */
|
||||
0x00cf00, /* Forest */
|
||||
0x007f3f, /* Taiga */
|
||||
0x3f7f00, /* Swampland */
|
||||
0x003fff, /* River */
|
||||
0x7f0000, /* Hell */
|
||||
0x007fff, /* Sky */
|
||||
0x3f3fff, /* Frozen Ocean */
|
||||
0x3f3fff, /* Frozen River */
|
||||
0x7fffcf, /* Ice Plains */
|
||||
0x3fcf7f, /* Ice Mountains */
|
||||
0xcf00cf, /* Mushroom Island */
|
||||
0x7f00ff, /* Mushroom Island Shore */
|
||||
0xffff3f, /* Beach */
|
||||
0xcfcf00, /* Desert Hills */
|
||||
0x00cf3f, /* Forest Hills */
|
||||
0x006f1f, /* Taiga Hills */
|
||||
0x7f8f7f, /* Extreme Hills Edge */
|
||||
0x004f00, /* Jungle */
|
||||
0x003f00, /* Jungle Hills */
|
||||
} ;
|
||||
|
||||
return BiomeColor[a_Biome];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeRenderer::MoveViewBy(int a_OffsX, int a_OffsY)
|
||||
{
|
||||
m_OriginX += a_OffsX;
|
||||
m_OriginY += a_OffsY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// BiomeRenderer.cpp
|
||||
|
||||
// Implements the cBiomeRenderer class representing the rendering engine
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeRenderer.h"
|
||||
#include "Pixmap.h"
|
||||
#include "Timer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeRenderer::cBiomeRenderer(void) :
|
||||
m_OriginX(160),
|
||||
m_OriginY(160),
|
||||
m_Zoom(1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeRenderer::SetSource(cBiomeSource * a_Source)
|
||||
{
|
||||
m_Cache.SetSource(a_Source);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeRenderer::Render(cPixmap & a_Pixmap)
|
||||
{
|
||||
cTimer Timer("cBiomeRenderer::Render");
|
||||
|
||||
int Wid = a_Pixmap.GetWidth();
|
||||
int Hei = a_Pixmap.GetHeight();
|
||||
|
||||
// Hint the approximate view area to the biome source so that it can adjust its caches:
|
||||
int MinBlockX = ( - m_OriginX) / m_Zoom;
|
||||
int MaxBlockX = (Wid - m_OriginX) / m_Zoom;
|
||||
int MinBlockZ = ( - m_OriginY) / m_Zoom;
|
||||
int MaxBlockZ = (Hei - m_OriginY) / m_Zoom;
|
||||
m_Cache.HintViewArea(MinBlockX / 16 - 1, MaxBlockX / 16 + 1, MinBlockZ / 16 - 1, MaxBlockZ / 16 + 1);
|
||||
|
||||
// Hold one current chunk of biome data:
|
||||
int CurChunkX = -10000;
|
||||
int CurChunkZ = -10000;
|
||||
cChunkDef::BiomeMap CurBiomes;
|
||||
|
||||
bool res = false;
|
||||
|
||||
for (int y = 0; y < Hei; y++)
|
||||
{
|
||||
int BlockZ = (y - m_OriginY) / m_Zoom;
|
||||
int ChunkZ = (BlockZ >= 0) ? (BlockZ / 16) : ((BlockZ + 1) / 16 - 1);
|
||||
int RelZ = BlockZ - ChunkZ * 16;
|
||||
for (int x = 0; x < Wid; x++)
|
||||
{
|
||||
int BlockX = (x - m_OriginX) / m_Zoom;
|
||||
int ChunkX = (BlockX >= 0) ? (BlockX / 16) : ((BlockX + 1) / 16 - 1);
|
||||
int RelX = BlockX - ChunkX * 16;
|
||||
if ((ChunkZ != CurChunkZ) || (ChunkX != CurChunkX))
|
||||
{
|
||||
CurChunkX = ChunkX;
|
||||
CurChunkZ = ChunkZ;
|
||||
switch (m_Cache.GetBiome(CurChunkX, CurChunkZ, CurBiomes))
|
||||
{
|
||||
case cBiomeSource::baLater:
|
||||
{
|
||||
res = true;
|
||||
// fallthrough:
|
||||
}
|
||||
case cBiomeSource::baNever:
|
||||
{
|
||||
for (int i = 0; i < ARRAYCOUNT(CurBiomes); i++)
|
||||
{
|
||||
CurBiomes[i] = (EMCSBiome)-1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // switch (Biome availability)
|
||||
}
|
||||
EMCSBiome Biome = cChunkDef::GetBiome(CurBiomes, RelX, RelZ);
|
||||
a_Pixmap.SetPixel(x, y, GetBiomeColor(Biome));
|
||||
} // for x
|
||||
} // for y
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cBiomeRenderer::GetBiomeColor(EMCSBiome a_Biome)
|
||||
{
|
||||
if ((a_Biome < 0) || (a_Biome > biMaxBiome))
|
||||
{
|
||||
return 0xcfcfcf; // LtGray for unknown biomes
|
||||
}
|
||||
|
||||
static int BiomeColor[] =
|
||||
{
|
||||
// RGB:
|
||||
0x0000ff, /* Ocean */
|
||||
0x00cf3f, /* Plains */
|
||||
0xffff00, /* Desert */
|
||||
0x7f7f7f, /* Extreme Hills */
|
||||
0x00cf00, /* Forest */
|
||||
0x007f3f, /* Taiga */
|
||||
0x3f7f00, /* Swampland */
|
||||
0x003fff, /* River */
|
||||
0x7f0000, /* Hell */
|
||||
0x007fff, /* Sky */
|
||||
0x3f3fff, /* Frozen Ocean */
|
||||
0x3f3fff, /* Frozen River */
|
||||
0x7fffcf, /* Ice Plains */
|
||||
0x3fcf7f, /* Ice Mountains */
|
||||
0xcf00cf, /* Mushroom Island */
|
||||
0x7f00ff, /* Mushroom Island Shore */
|
||||
0xffff3f, /* Beach */
|
||||
0xcfcf00, /* Desert Hills */
|
||||
0x00cf3f, /* Forest Hills */
|
||||
0x006f1f, /* Taiga Hills */
|
||||
0x7f8f7f, /* Extreme Hills Edge */
|
||||
0x004f00, /* Jungle */
|
||||
0x003f00, /* Jungle Hills */
|
||||
} ;
|
||||
|
||||
return BiomeColor[a_Biome];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeRenderer::MoveViewBy(int a_OffsX, int a_OffsY)
|
||||
{
|
||||
m_OriginX += a_OffsX;
|
||||
m_OriginY += a_OffsY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,50 +1,50 @@
|
||||
|
||||
// BiomeRenderer.h
|
||||
|
||||
// Declares the cBiomeRenderer class representing the rendering engine
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BiomeCache.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd: Pixmap.h
|
||||
class cPixmap;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeRenderer
|
||||
{
|
||||
public:
|
||||
cBiomeRenderer(void);
|
||||
|
||||
void SetSource(cBiomeSource * a_Source); // Takes ownership of the source
|
||||
|
||||
/// Renders the biomes into the given pixmap. Returns true if some biome data was missing and can be retrieved later
|
||||
bool Render(cPixmap & a_Pixmap);
|
||||
|
||||
/// Returns the RGB color value for the specified biome
|
||||
int GetBiomeColor(EMCSBiome a_Biome);
|
||||
|
||||
void MoveViewBy(int a_OffsX, int a_OffsY);
|
||||
|
||||
protected:
|
||||
cBiomeCache m_Cache;
|
||||
|
||||
int m_OriginX;
|
||||
int m_OriginY;
|
||||
int m_Zoom;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// BiomeRenderer.h
|
||||
|
||||
// Declares the cBiomeRenderer class representing the rendering engine
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BiomeCache.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd: Pixmap.h
|
||||
class cPixmap;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeRenderer
|
||||
{
|
||||
public:
|
||||
cBiomeRenderer(void);
|
||||
|
||||
void SetSource(cBiomeSource * a_Source); // Takes ownership of the source
|
||||
|
||||
/// Renders the biomes into the given pixmap. Returns true if some biome data was missing and can be retrieved later
|
||||
bool Render(cPixmap & a_Pixmap);
|
||||
|
||||
/// Returns the RGB color value for the specified biome
|
||||
int GetBiomeColor(EMCSBiome a_Biome);
|
||||
|
||||
void MoveViewBy(int a_OffsX, int a_OffsY);
|
||||
|
||||
protected:
|
||||
cBiomeCache m_Cache;
|
||||
|
||||
int m_OriginX;
|
||||
int m_OriginY;
|
||||
int m_Zoom;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,37 +1,37 @@
|
||||
|
||||
// BiomeSource.h
|
||||
|
||||
// Declares the cBiomeSource abstract class used as an interface for getting biomes from any source
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "ChunkDef.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeSource abstract
|
||||
{
|
||||
public:
|
||||
enum eAvailability
|
||||
{
|
||||
baNow, // Data returned now
|
||||
baLater, // Data not returned, but will be available later, try again after a while
|
||||
baNever, // Data not returned, will not be available at all
|
||||
} ;
|
||||
|
||||
/// Fills a_Biomes with the biomes for the chunk specified
|
||||
virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) = 0;
|
||||
|
||||
/// Used to inform the source about the view area that will be queried in the near future.
|
||||
virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) = 0;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// BiomeSource.h
|
||||
|
||||
// Declares the cBiomeSource abstract class used as an interface for getting biomes from any source
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "ChunkDef.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeSource abstract
|
||||
{
|
||||
public:
|
||||
enum eAvailability
|
||||
{
|
||||
baNow, // Data returned now
|
||||
baLater, // Data not returned, but will be available later, try again after a while
|
||||
baNever, // Data not returned, will not be available at all
|
||||
} ;
|
||||
|
||||
/// Fills a_Biomes with the biomes for the chunk specified
|
||||
virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) = 0;
|
||||
|
||||
/// Used to inform the source about the view area that will be queried in the near future.
|
||||
virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) = 0;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,190 +1,190 @@
|
||||
|
||||
// BiomeViewWnd.cpp
|
||||
|
||||
// Implements the cBiomeViewWnd class representing the window that displays biomes
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeViewWnd.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "GeneratorBiomeSource.h"
|
||||
#include "../iniFile/iniFile.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int TIMER_RERENDER = 1200;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeViewWnd::cBiomeViewWnd(void) :
|
||||
m_Wnd(NULL),
|
||||
m_Thunk(&cBiomeViewWnd::WndProc, this),
|
||||
m_IsLButtonDown(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeViewWnd::Create(HWND a_ParentWnd, LPCTSTR a_Title)
|
||||
{
|
||||
ASSERT(m_Wnd == NULL);
|
||||
|
||||
// Create a regular STATIC window, then override its window procedure with our own. No need for obnoxious RegisterWindowClass() stuff.
|
||||
m_Wnd = CreateWindow("STATIC", a_Title, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 400, 300, a_ParentWnd, NULL, GetModuleHandle(NULL), NULL);
|
||||
if (m_Wnd == NULL)
|
||||
{
|
||||
LOGERROR("Cannot create main window: %d", GetLastError());
|
||||
return false;
|
||||
}
|
||||
SetWindowLongPtr(m_Wnd, GWLP_WNDPROC, m_Thunk);
|
||||
|
||||
cIniFile IniFile;
|
||||
cBiomeGen * BioGen = new cBioGenMultiStepMap(2);
|
||||
BioGen->Initialize(IniFile);
|
||||
m_Renderer.SetSource(new cGeneratorBiomeSource(BioGen));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (a_Msg)
|
||||
{
|
||||
case WM_CLOSE: return OnClose();
|
||||
case WM_COMMAND: return OnCommand(wParam, lParam);
|
||||
case WM_LBUTTONDOWN: return OnLButtonDown(wParam, lParam);
|
||||
case WM_LBUTTONUP: return OnLButtonUp (wParam, lParam);
|
||||
case WM_MOUSEMOVE: return OnMouseMove (wParam, lParam);
|
||||
case WM_PAINT: return OnPaint();
|
||||
case WM_TIMER: return OnTimer(wParam);
|
||||
}
|
||||
return ::DefWindowProc(a_Wnd, a_Msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnClose(void)
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// TODO: Handle menu commands, when we get menu
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
m_IsLButtonDown = true;
|
||||
GetCursorPos(&m_MouseDown);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnMouseMove(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!m_IsLButtonDown)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
POINT pnt;
|
||||
GetCursorPos(&pnt);
|
||||
m_Renderer.MoveViewBy(pnt.x - m_MouseDown.x, pnt.y - m_MouseDown.y);
|
||||
if (m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
SetTimer(m_Wnd, TIMER_RERENDER, 200, NULL);
|
||||
}
|
||||
m_MouseDown = pnt;
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnLButtonUp(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
OnMouseMove(wParam, lParam); // Last movement - if the mouse move hasn't been reported due to speed
|
||||
m_IsLButtonDown = false;
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnPaint(void)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC DC = BeginPaint(m_Wnd, &ps);
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(m_Wnd, &rc);
|
||||
int Wid = rc.right - rc.left;
|
||||
int Hei = rc.bottom - rc.top;
|
||||
if ((m_Pixmap.GetWidth() != Wid) || (m_Pixmap.GetHeight() != Hei))
|
||||
{
|
||||
m_Pixmap.SetSize(Wid, Hei);
|
||||
if (m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
SetTimer(m_Wnd, TIMER_RERENDER, 200, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
m_Pixmap.DrawToDC(DC, 0, 0);
|
||||
|
||||
EndPaint(m_Wnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnTimer(WPARAM wParam)
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case TIMER_RERENDER:
|
||||
{
|
||||
if (!m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
KillTimer(m_Wnd, TIMER_RERENDER);
|
||||
}
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// BiomeViewWnd.cpp
|
||||
|
||||
// Implements the cBiomeViewWnd class representing the window that displays biomes
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeViewWnd.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "GeneratorBiomeSource.h"
|
||||
#include "../iniFile/iniFile.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int TIMER_RERENDER = 1200;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeViewWnd::cBiomeViewWnd(void) :
|
||||
m_Wnd(NULL),
|
||||
m_Thunk(&cBiomeViewWnd::WndProc, this),
|
||||
m_IsLButtonDown(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeViewWnd::Create(HWND a_ParentWnd, LPCTSTR a_Title)
|
||||
{
|
||||
ASSERT(m_Wnd == NULL);
|
||||
|
||||
// Create a regular STATIC window, then override its window procedure with our own. No need for obnoxious RegisterWindowClass() stuff.
|
||||
m_Wnd = CreateWindow("STATIC", a_Title, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 400, 300, a_ParentWnd, NULL, GetModuleHandle(NULL), NULL);
|
||||
if (m_Wnd == NULL)
|
||||
{
|
||||
LOGERROR("Cannot create main window: %d", GetLastError());
|
||||
return false;
|
||||
}
|
||||
SetWindowLongPtr(m_Wnd, GWLP_WNDPROC, m_Thunk);
|
||||
|
||||
cIniFile IniFile;
|
||||
cBiomeGen * BioGen = new cBioGenMultiStepMap(2);
|
||||
BioGen->Initialize(IniFile);
|
||||
m_Renderer.SetSource(new cGeneratorBiomeSource(BioGen));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (a_Msg)
|
||||
{
|
||||
case WM_CLOSE: return OnClose();
|
||||
case WM_COMMAND: return OnCommand(wParam, lParam);
|
||||
case WM_LBUTTONDOWN: return OnLButtonDown(wParam, lParam);
|
||||
case WM_LBUTTONUP: return OnLButtonUp (wParam, lParam);
|
||||
case WM_MOUSEMOVE: return OnMouseMove (wParam, lParam);
|
||||
case WM_PAINT: return OnPaint();
|
||||
case WM_TIMER: return OnTimer(wParam);
|
||||
}
|
||||
return ::DefWindowProc(a_Wnd, a_Msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnClose(void)
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// TODO: Handle menu commands, when we get menu
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
m_IsLButtonDown = true;
|
||||
GetCursorPos(&m_MouseDown);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnMouseMove(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!m_IsLButtonDown)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
POINT pnt;
|
||||
GetCursorPos(&pnt);
|
||||
m_Renderer.MoveViewBy(pnt.x - m_MouseDown.x, pnt.y - m_MouseDown.y);
|
||||
if (m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
SetTimer(m_Wnd, TIMER_RERENDER, 200, NULL);
|
||||
}
|
||||
m_MouseDown = pnt;
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnLButtonUp(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
OnMouseMove(wParam, lParam); // Last movement - if the mouse move hasn't been reported due to speed
|
||||
m_IsLButtonDown = false;
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnPaint(void)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC DC = BeginPaint(m_Wnd, &ps);
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(m_Wnd, &rc);
|
||||
int Wid = rc.right - rc.left;
|
||||
int Hei = rc.bottom - rc.top;
|
||||
if ((m_Pixmap.GetWidth() != Wid) || (m_Pixmap.GetHeight() != Hei))
|
||||
{
|
||||
m_Pixmap.SetSize(Wid, Hei);
|
||||
if (m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
SetTimer(m_Wnd, TIMER_RERENDER, 200, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
m_Pixmap.DrawToDC(DC, 0, 0);
|
||||
|
||||
EndPaint(m_Wnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnTimer(WPARAM wParam)
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case TIMER_RERENDER:
|
||||
{
|
||||
if (!m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
KillTimer(m_Wnd, TIMER_RERENDER);
|
||||
}
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,46 +1,46 @@
|
||||
|
||||
// BiomeViewWnd.h
|
||||
|
||||
// Declares the cBiomeViewWnd class representing the window that displays biomes
|
||||
|
||||
#include "WndProcThunk.h"
|
||||
#include "BiomeRenderer.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "Pixmap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeViewWnd
|
||||
{
|
||||
public:
|
||||
cBiomeViewWnd(void);
|
||||
|
||||
bool Create(HWND a_ParentWnd, LPCTSTR a_Title);
|
||||
|
||||
protected:
|
||||
HWND m_Wnd;
|
||||
CWndProcThunk<cBiomeViewWnd> m_Thunk;
|
||||
|
||||
cBiomeRenderer m_Renderer;
|
||||
cPixmap m_Pixmap;
|
||||
|
||||
bool m_IsLButtonDown;
|
||||
POINT m_MouseDown;
|
||||
|
||||
LRESULT WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// Message handlers:
|
||||
LRESULT OnClose (void);
|
||||
LRESULT OnCommand (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnMouseMove (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnLButtonUp (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnPaint (void);
|
||||
LRESULT OnTimer (WPARAM wParam);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// BiomeViewWnd.h
|
||||
|
||||
// Declares the cBiomeViewWnd class representing the window that displays biomes
|
||||
|
||||
#include "WndProcThunk.h"
|
||||
#include "BiomeRenderer.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "Pixmap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeViewWnd
|
||||
{
|
||||
public:
|
||||
cBiomeViewWnd(void);
|
||||
|
||||
bool Create(HWND a_ParentWnd, LPCTSTR a_Title);
|
||||
|
||||
protected:
|
||||
HWND m_Wnd;
|
||||
CWndProcThunk<cBiomeViewWnd> m_Thunk;
|
||||
|
||||
cBiomeRenderer m_Renderer;
|
||||
cPixmap m_Pixmap;
|
||||
|
||||
bool m_IsLButtonDown;
|
||||
POINT m_MouseDown;
|
||||
|
||||
LRESULT WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// Message handlers:
|
||||
LRESULT OnClose (void);
|
||||
LRESULT OnCommand (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnMouseMove (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnLButtonUp (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnPaint (void);
|
||||
LRESULT OnTimer (WPARAM wParam);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,52 +1,52 @@
|
||||
|
||||
// BiomeVisualiser.cpp
|
||||
|
||||
// Implements the cBiomeVisualiser class representing the entire app. Also implements the WinMain() entrypoint
|
||||
|
||||
#include "Globals.h"
|
||||
#include "time.h"
|
||||
#include "BiomeVisualiser.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int WINAPI WinMain(HINSTANCE a_Instance, HINSTANCE a_PrevInstance, LPSTR a_CmdLine, int a_ShowCmd)
|
||||
{
|
||||
cBiomeVisualiser App;
|
||||
return App.Run();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeVisualiser::cBiomeVisualiser(void)
|
||||
// : m_Logger(Printf("BiomeVisualiser_%08x", time(NULL)))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cBiomeVisualiser::Run(void)
|
||||
{
|
||||
if (!m_MainWnd.Create(GetDesktopWindow(), TEXT("BiomeVisualiser")))
|
||||
{
|
||||
LOGERROR("Cannot create main window: %d", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
} // while (GetMessage)
|
||||
return msg.lParam;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// BiomeVisualiser.cpp
|
||||
|
||||
// Implements the cBiomeVisualiser class representing the entire app. Also implements the WinMain() entrypoint
|
||||
|
||||
#include "Globals.h"
|
||||
#include "time.h"
|
||||
#include "BiomeVisualiser.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int WINAPI WinMain(HINSTANCE a_Instance, HINSTANCE a_PrevInstance, LPSTR a_CmdLine, int a_ShowCmd)
|
||||
{
|
||||
cBiomeVisualiser App;
|
||||
return App.Run();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeVisualiser::cBiomeVisualiser(void)
|
||||
// : m_Logger(Printf("BiomeVisualiser_%08x", time(NULL)))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cBiomeVisualiser::Run(void)
|
||||
{
|
||||
if (!m_MainWnd.Create(GetDesktopWindow(), TEXT("BiomeVisualiser")))
|
||||
{
|
||||
LOGERROR("Cannot create main window: %d", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
} // while (GetMessage)
|
||||
return msg.lParam;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,31 +1,31 @@
|
||||
|
||||
// BiomeVisualiser.h
|
||||
|
||||
// Declares the cBiomeVisualiser class representing the entire application
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "BiomeViewWnd.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeVisualiser
|
||||
{
|
||||
public:
|
||||
cBiomeVisualiser(void);
|
||||
|
||||
int Run(void);
|
||||
|
||||
protected:
|
||||
cBiomeViewWnd m_MainWnd;
|
||||
|
||||
cMCLogger m_Logger;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// BiomeVisualiser.h
|
||||
|
||||
// Declares the cBiomeVisualiser class representing the entire application
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "BiomeViewWnd.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeVisualiser
|
||||
{
|
||||
public:
|
||||
cBiomeVisualiser(void);
|
||||
|
||||
int Run(void);
|
||||
|
||||
protected:
|
||||
cBiomeViewWnd m_MainWnd;
|
||||
|
||||
cMCLogger m_Logger;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,23 +1,23 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BiomeVisualiser", "BiomeVisualiser.vcproj", "{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release profiled|Win32 = Release profiled|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release profiled|Win32.Build.0 = Release profiled|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BiomeVisualiser", "BiomeVisualiser.vcproj", "{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release profiled|Win32 = Release profiled|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release profiled|Win32.Build.0 = Release profiled|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user