From d1b8dbcaf8ad171a3333d80d8a1d23c9ca09131f Mon Sep 17 00:00:00 2001 From: Indota Date: Tue, 24 Sep 2013 22:20:10 -0400 Subject: [PATCH 1/9] Added Readme Added ReadMe File for repository description. --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..6002bc2 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +SWG:ANH Documentation +=========== + +Welcome to the SWG:ANH Documentation Repository. This repository provides informational guides, information, and tutorials on using SWG:ANH tools and services. + + +Browse the various folders to find what you are looking for. If you need help, please do not hesitate to ask on our forums. From c40e2a576d219440cad65db1913da412e8ac57aa Mon Sep 17 00:00:00 2001 From: Indota Date: Tue, 24 Sep 2013 22:21:38 -0400 Subject: [PATCH 2/9] Updated Readme Grammar Error! --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6002bc2..8b94227 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ SWG:ANH Documentation =========== -Welcome to the SWG:ANH Documentation Repository. This repository provides informational guides, information, and tutorials on using SWG:ANH tools and services. +Welcome to the SWG:ANH Documentation Repository. This repository provides guides, information, and tutorials on using SWG:ANH tools and services. Browse the various folders to find what you are looking for. If you need help, please do not hesitate to ask on our forums. From 69242f06bdfb64a01f83efbe37d5e8f6c63595a8 Mon Sep 17 00:00:00 2001 From: Indota Date: Tue, 24 Sep 2013 22:45:34 -0400 Subject: [PATCH 3/9] Moving all files to Archive Directory --- old/CMakeLists.txt | 93 +++++ old/book/architecture.rst | 11 + old/book/events.rst | 33 ++ old/book/index.rst | 14 + old/book/installation.rst | 17 + old/book/installation_client.rst | 3 + old/book/installation_docs.rst | 70 ++++ old/book/installation_linux.rst | 176 +++++++++ old/book/installation_windows.rst | 165 ++++++++ old/book/map.rst.inc | 6 + old/book/plugins.rst | 7 + old/book/scripting.rst | 13 + old/book/services.rst | 7 + old/conf.py.in | 216 ++++++++++ old/contributing/index.rst | 14 + old/contributing/issues.rst | 32 ++ old/contributing/license.rst | 16 + old/contributing/map.rst.inc | 7 + old/contributing/pull_requests.rst | 152 +++++++ old/contributing/security.rst | 19 + old/contributing/standards.rst | 62 +++ old/contributing/tests.rst | 38 ++ old/cookbook/index.rst | 13 + old/cookbook/map.rst.inc | 11 + old/cookbook/plugins/best_practices.rst | 48 +++ old/cookbook/scripting/command_scripts.rst | 372 ++++++++++++++++++ .../security/custom_authentication.rst | 14 + .../contributing/pull_requests_image_1.png | Bin 0 -> 27759 bytes old/index.rst | 28 ++ old/pythonapi/command.rst | 18 + old/pythonapi/creature.rst | 83 ++++ old/pythonapi/index.rst | 13 + old/pythonapi/kernel.rst | 16 + old/pythonapi/map.rst.inc | 6 + old/pythonapi/object.rst | 7 + old/pythonapi/object_controller.rst | 14 + old/pythonapi/objects.rst | 11 + old/pythonapi/player.rst | 39 ++ old/pythonapi/services.rst | 73 ++++ old/pythonapi/tangible.rst | 6 + old/pythonapi/utility.rst | 7 + old/tools/cmake/FindSphinx.cmake | 37 ++ old/tools/windows/user_project.vcxproj.in | 11 + 43 files changed, 1998 insertions(+) create mode 100644 old/CMakeLists.txt create mode 100644 old/book/architecture.rst create mode 100644 old/book/events.rst create mode 100644 old/book/index.rst create mode 100644 old/book/installation.rst create mode 100644 old/book/installation_client.rst create mode 100644 old/book/installation_docs.rst create mode 100644 old/book/installation_linux.rst create mode 100644 old/book/installation_windows.rst create mode 100644 old/book/map.rst.inc create mode 100644 old/book/plugins.rst create mode 100644 old/book/scripting.rst create mode 100644 old/book/services.rst create mode 100644 old/conf.py.in create mode 100644 old/contributing/index.rst create mode 100644 old/contributing/issues.rst create mode 100644 old/contributing/license.rst create mode 100644 old/contributing/map.rst.inc create mode 100644 old/contributing/pull_requests.rst create mode 100644 old/contributing/security.rst create mode 100644 old/contributing/standards.rst create mode 100644 old/contributing/tests.rst create mode 100644 old/cookbook/index.rst create mode 100644 old/cookbook/map.rst.inc create mode 100644 old/cookbook/plugins/best_practices.rst create mode 100644 old/cookbook/scripting/command_scripts.rst create mode 100644 old/cookbook/security/custom_authentication.rst create mode 100644 old/images/contributing/pull_requests_image_1.png create mode 100644 old/index.rst create mode 100644 old/pythonapi/command.rst create mode 100644 old/pythonapi/creature.rst create mode 100644 old/pythonapi/index.rst create mode 100644 old/pythonapi/kernel.rst create mode 100644 old/pythonapi/map.rst.inc create mode 100644 old/pythonapi/object.rst create mode 100644 old/pythonapi/object_controller.rst create mode 100644 old/pythonapi/objects.rst create mode 100644 old/pythonapi/player.rst create mode 100644 old/pythonapi/services.rst create mode 100644 old/pythonapi/tangible.rst create mode 100644 old/pythonapi/utility.rst create mode 100644 old/tools/cmake/FindSphinx.cmake create mode 100644 old/tools/windows/user_project.vcxproj.in diff --git a/old/CMakeLists.txt b/old/CMakeLists.txt new file mode 100644 index 0000000..2c1f5d9 --- /dev/null +++ b/old/CMakeLists.txt @@ -0,0 +1,93 @@ +cmake_minimum_required(VERSION 2.8) + +project(swganh-docs CXX) + +# current version +if(NOT DEFINED swganh_VERSION) + set(swganh_VERSION_MAJOR 0) + set(swganh_VERSION_MINOR 4) + set(swganh_VERSION_PATCH 0) + set(swganh_VERSION + ${swganh_VERSION_MAJOR}.${swganh_VERSION_MINOR}.${swganh_VERSION_PATCH}) +endif() + +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/tools/cmake") + +find_package(Sphinx REQUIRED) + +if(NOT DEFINED SPHINX_THEME) + set(SPHINX_THEME default) +endif() + +if(NOT DEFINED SPHINX_THEME_DIR) + set(SPHINX_THEME_DIR) +endif() + +# configured documentation tools and intermediate build results +set(BINARY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/_build") + +# Sphinx cache with pickled ReST documents +set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees") + +# HTML output directory +set(SPHINX_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/html") + +if(NOT DEFINED SWGPY_DIR) + set(SWGPY_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +endif() + +if(WIN32) + foreach(configuration ${CMAKE_CONFIGURATION_TYPES}) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in" + "${BINARY_BUILD_DIR}/${configuration}/conf.py" + @ONLY) + endforeach() + + set(BINARY_BUILD_DIR "${BINARY_BUILD_DIR}/$") + set(SPHINX_CACHE_DIR "${SPHINX_CACHE_DIR}/$") + set(SPHINX_HTML_DIR "${SPHINX_HTML_DIR}/$") +else() + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in" + "${BINARY_BUILD_DIR}/conf.py" + @ONLY) +endif() + +file(GLOB_RECURSE DOCUMENTS *.rst *.in) + +# Group the source files based on the directory structure. +FOREACH(__source_file ${DOCUMENTS}) + STRING(REGEX REPLACE "(${CMAKE_CURRENT_SOURCE_DIR}/)((.*/)*)(.*)" "\\2" __source_dir "${__source_file}") + STRING(REGEX REPLACE "(${CMAKE_CURRENT_SOURCE_DIR}/${__source_dir})(.*)" "\\2" __source_filename "${__source_file}") + + STRING(REPLACE "/" "\\\\" __source_group "${__source_dir}") + SOURCE_GROUP("${__source_group}" FILES ${__source_file}) +ENDFOREACH() + +if(WIN32) + set(WORKING_DIR "${SWGPY_DIR}/$\(Configuration\)") + set(DEPENDENCIES swgpy) +else() + set(WORKING_DIR "${SWGPY_DIR}") + set(DEPENDENCIES) +endif() + +add_custom_target(swganh_doc_html ALL + ${SPHINX_EXECUTABLE} + -q -b html + -c "${BINARY_BUILD_DIR}" + -d "${SPHINX_CACHE_DIR}" + -n + "${CMAKE_CURRENT_SOURCE_DIR}" + "${SPHINX_HTML_DIR}" + COMMENT "Building HTML documentation with Sphinx" + DEPENDS ${DEPENDENCIES} + WORKING_DIRECTORY "${WORKING_DIR}" + VERBATIM + SOURCES ${DOCUMENTS} +) + +configure_file( + ${PROJECT_SOURCE_DIR}/tools/windows/user_project.vcxproj.in + ${CMAKE_CURRENT_BINARY_DIR}/swganh_doc_html.vcxproj.user @ONLY) \ No newline at end of file diff --git a/old/book/architecture.rst b/old/book/architecture.rst new file mode 100644 index 0000000..10e9514 --- /dev/null +++ b/old/book/architecture.rst @@ -0,0 +1,11 @@ +========================================= +Server Architecture and Design Philosophy +========================================= + +Main Application Parts + +* ANH Library: general game engine (static library) +* SWGANH Library: swg precu14 game library (static library plugin) +* 3rd Party Plugins: plugins that extend or modify the functionality of the SWGANH Library +* SWGANH Executable: the application that is executed, loads swganh library and plugins + diff --git a/old/book/events.rst b/old/book/events.rst new file mode 100644 index 0000000..2f72f9c --- /dev/null +++ b/old/book/events.rst @@ -0,0 +1,33 @@ +Events +====== + +Massively multiplayer online games are by necessity big. Really, really big. Think for just a moment about all the different categories of features that make up a game (referred to in the MMOServer code as **Services**): crafting, combat, chat, trading, movement... and the list can easily go on for some time. There is so much functionality provided by these services that in mots MMORPGs they need to be run across multiple processes and/or physical machines. + +Alright, we've established that the scope of developing a MMORPG is rediculous, if you don't believe me just ask for helpful starting advice at `StackOverflow`_ or `GameDev.net`_ [1]_. Still with me? Good, insanity is a must to proceed. Now you might be thinking: how do we manage all of this complexity without it turning into a big bowl of code spaghetti? + +The key to managing the complexity of many interacting services is good communication. There are two ways in which services need to communicate with each other: to inform an unknown number of interested parties that something significant has occurred (via the **Event Dispatcher**) and to make requests directly to a specific type of service (via the **Service Locator**). This article focuses on the motivation behind the Event Dispatcher and common usage patterns to help you quickly get up to speed with one of the most vital components of the SWG:ANH MMOServer engine. + +Overview +-------- + +The Event Dispatcher consists of three main components starting with the **dispatcher** that serves as the focal point for services to communicate their current state with one another. Service helper objects, known as **listeners**, **connect** to the dispatcher and wait for specific types of messages, or **events**, to be **delivered**. Other services **notify** the dispatcher that an event has occurred, which in turn notifies all the listeners that have expressed interest in that event type. + +Events +------ + +Events are a way for a service to package information about an observable behavior that is either being performed or about to be performed. They are like a standardized language that all services have agreed upon as an acceptible way to communicate with one another. + +The most basic event type is, unsurprisingly, called the basic_event. It consists of a **subject**, the object responsible for invoking the event, and the **event data**, a collection of information that gives context for the event. + +Event Dispatcher +---------------- + + +Listeners +--------- + + +.. [1] If you're a hobbiest programmer with a mind on building an MMORPG expect to be met with many a "don't do it" suggestions along the way. + +.. _`StackOverflow`: http://www.stackoverflow.com +.. _`GameDev.net`: http://www.gamedev.net \ No newline at end of file diff --git a/old/book/index.rst b/old/book/index.rst new file mode 100644 index 0000000..a67100c --- /dev/null +++ b/old/book/index.rst @@ -0,0 +1,14 @@ +SWGANH Reference +================ + +.. toctree:: + :hidden: + + installation + architecture + services + plugins + events + scripting + +.. include:: /book/map.rst.inc diff --git a/old/book/installation.rst b/old/book/installation.rst new file mode 100644 index 0000000..912f1a1 --- /dev/null +++ b/old/book/installation.rst @@ -0,0 +1,17 @@ +================================= +Installing and Configuring SWGANH +================================= + +* :doc:`/book/installation_windows` +* :doc:`/book/installation_linux` +* :doc:`/book/installation_docs` +* :doc:`/book/installation_client` + + +.. toctree:: + :hidden: + + installation_windows + installation_linux + installation_docs + installation_client diff --git a/old/book/installation_client.rst b/old/book/installation_client.rst new file mode 100644 index 0000000..8e20183 --- /dev/null +++ b/old/book/installation_client.rst @@ -0,0 +1,3 @@ +======================== +Game Client Installation +======================== diff --git a/old/book/installation_docs.rst b/old/book/installation_docs.rst new file mode 100644 index 0000000..eb31624 --- /dev/null +++ b/old/book/installation_docs.rst @@ -0,0 +1,70 @@ +=========================== +Documentation Install Guide +=========================== + +This guide is a walkthrough on setting up the SWGANH documentation to build as part of an existing SWGANH environment. For more information on how to set up SWGANH please see the relevant documentation. + +Sphinx +~~~~~~ + +Sphinx is used to generate the SWGANH developer documentation. + + +Sphinx on Windows +----------------- + +To install it on windows you need to first download and install the distribute package. Git Bash is recommend over the windows command prompt to run the following as it already comes with the **curl** utility. + +:: + + curl -O http://python-distribute.org/distribute_setup.py + python distribute_setup.py + easy_install Sphinx + +.. NOTE:: + + It is important that Sphinx is installed with support for Python3. The key to this is ensuring you install Sphinx using an easy_install (via the distribute package) that was built against Python 3. + +.. WARNING:: + + If you get an error stating "Bad file number" it may indicate a confict with UAC. To get around this open a normal windows command prompt and enter the command. + + :: + + easy_install Sphinx + +You will also need to add the path to Sphinx to the system PATH. In a default Python 3.2 install this path is `C:/Python32/Scripts`. + +Sphinx on Linux +---------------- + +To install it on Ubuntu use the following command: + +:: + + sudo easy_install3 Sphinx + +.. NOTE:: + + It is important that Sphinx is installed with support for Python3. The key to this is ensuring you install Sphinx using an easy_install (via the distribute package) that was built against Python 3. + + +Checkout and Build the Documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Right click on the swganh project directory (e.g. `C:/workspace/swganh`) and choose "to open "Git Bash here". Next we'll use git to checkout the latest version of the documentation source. + +:: + + git clone https://github.com/anhstudios/swganh-docs.git docs + +Run the following commands to generate the project and build the source with the documentation. + +:: + + cd build + cmake .. + cmake --build . + +This will kick off a full build of the project. The final documentation output can be found at `C:/workspace/swganh/build/docs/html/Debug`. + diff --git a/old/book/installation_linux.rst b/old/book/installation_linux.rst new file mode 100644 index 0000000..9f11755 --- /dev/null +++ b/old/book/installation_linux.rst @@ -0,0 +1,176 @@ +=================== +Linux Install Guide +=================== + +This chapter cover's the setup of SWGANH from source in a linux environment. This particular guide cover's installation using Ubuntu and should apply directly to most debian based flavors. Other flavors of linux should at minimum support GCC 4.6 and Python3. + +.. note:: + + This guide is based on Ubuntu 11.10. If you are building on another distro you may be required to install some of the 3rd party libraries manually. + +Installing Build Dependencies +----------------------------- + +The first step in a linux build is to ensure the major dependencies for building the project are installed and available. + +- Git 1.7+ +- GCC 4.6+ +- CMake 2.8.5+ +- Python 3.2+ +- GLM Math Library 0.9.2+ +- Boost 1.49+ +- Boost-Log 1.1+ +- TBB (Thread Building Blocks) 3.0+ +- Turtle 1.2 +- Mysql Server 5.1+ +- Mysql Connector C++ (Custom ANH Fork) + +In most cases modern linux distros will provide easily installable packages for most of the dependencies. First lets install the all the dependencies except for Boost, Mysql Connector C++ and Sphinx: + +:: + + sudo apt-get install g++ python3-dev libmysqlclient-dev mysql-server libtbb-dev libglm-dev git git-gui gitk subversion cmake make curl unzip libbz2-dev + +.. NOTE:: + + You may have noticed a few extra dependencies at the end, these are tools that'll make it easier to download and unpack files later on. + +During the installation of the above you will be asked to enter a password for the root mysql user. Be sure to remember this password for later in the installation process. + +The remaining dependencies require a little extra work to install properly on any linux distro. + +First up is Boost which needs to be linked specifically against Python3 so requires manual compilation and installation. In addition we make use of Boost-Log, a logging library that has been officially accepted into Boost but is currently in an incubation period. The interface is stable however and meets our requirments for logging. + +Download the latest source packages for Boost and Boost-log (at the time of this writing that is 1.49 and 1.1, respectively). + +:: + + curl -L -O http://downloads.sourceforge.net/project/boost/boost/1.49.0/boost_1_49_0.tar.bz2 + + svn co https://boost-log.svn.sourceforge.net/svnroot/boost-log/trunk/boost-log/ + +Next unpack both source packages and copy the Boost-log files into the main Boost package. + +:: + + tar -xvjf boost_1_49_0.tar.bz2 + + cp -R boost-log/boost/log boost_1_49_0/boost/log + cp -R boost-log/libs/log boost_1_49_0/libs/log + +When configuring its important to specify the version of Python that Boost should compile against. To do that navigate to the boost_1_49_0 directory and run the following command. + +:: + + cd boost_1_49_0 + ./bootstrap.sh --with-python=python3.2 + +Now that the environment is ready you can build boost by simply running the b2 command. + +:: + + ./b2 + sudo ./b2 install + +.. note:: + + Due to a bug in the bootstrap.sh file the Python root is not detected. For builds using the Ubuntu package version of Python this is not a problem, however, if you have installed Python to a non-standard location then you may get compile errors. In that case open up the **project-config.jam** file and add the path to the Python root as in the example below. + + :: + + python : 3.2 : /usr ; + +Turtle is a mocking library that is used for testing interactions between objects. This is a header only library and easy to install. Just download and unpack the library headers to the appropriate system path. + +:: + + cd ~ + curl -L -O http://downloads.sourceforge.net/project/turtle/turtle/1.2.0/turtle-1.2.0.tar.bz2 + sudo tar -xvjf turtle-1.2.0.tar.bz2 -C /usr/local + +This leaves only Mysql Connector C++ left on our list. This project is the official C++ connector from Mysql, however, it doesn't appear to be in active development at this time. For this reason we have had to create our own fork to support a few features that are missing from the official source. First make sure you're not in the Boost directory from the previous step and run the following: + +:: + + git clone https://github.com/anhstudios/mysql-connector-cpp.git + cd mysql-connector-cpp + cmake . + make + sudo make install + +Building the SWGANH Source +-------------------------- + +With the dependencies out of the way the hard part is over. It's now time to checkout the SWGANH source and kick off the first build. Make sure you're not still inside the Mysql Connector C++ directory from the previous section before running these commands. + +:: + + git clone https://github.com/anhstudios/swganh.git + mkdir swganh/build + cd swganh/build + cmake .. + make + +Setting up the Database +----------------------- + +A new database installation is needed before the server can be started for the first time. To install the server navigate to the `swganh/data/sql` folder and execute the following command: + +:: + + ./setup.sh -u MYSQL_USERNAME -p MYSQL_PASSWORD + +Replace MYSQL\_USERNAME and MYSQL\_PASSWORD with the authentication data of a mysql user with appropriate privileges. + +.. NOTE:: + + You can use the root user for simple local installations, however, it is advised that you create a dedicated mysql user for your SWGANH installation in production environments. + +.. NOTE:: + + You can set a custom host using the -h flag (e.g. -h 192.168.0.100). + + The mysql executable can also be customized via the -m flag (e.g. -m mysql5). + +Configuring and Running the Server +---------------------------------- + +You are now entering the home stretch, all that's left is to update the SWGANH configuration and kick off the server. + +Open the `swganh/build/bin/config/swganh.cfg` file and edit the following items. First you will need to update the **tre_config** setting with the path to the **live.cfg** file in your SWGANH Game Client directory. + +.. note:: + + Some older SWGANH clients have this file named as **swg2uu_live.cfg**. + +.. note:: + + The game client does not run on unix environments, in this case the easiest solution is to upload a client directory from an already existing windows installation. + +.. warning:: + + Be sure to specify the live.cfg file that is **inside** the SWGANH Game Client directory and **NOT** the one inside the official Star Wars Galaxies directory. + +Second, update the mysql database connection information with the address and user you used to setup the database in the previous section. + +Finally, set the address in the **service.connection** section to your public facing IP and then save and close the file. + +You can now kick off the server by running this command in the **swganh/build/bin** directory: + +:: + + ./swganh + +To start the server in a background process you can use a tool like screen. + +:: + + screen ./swganh + +Hitting **ctrl+a** then **ctrl+d** will disconnect from the screen session but will leave the server running in the background. You can rejoin the server to shut it down with the following command: + +:: + + screen -r + +No output is sent to the console, you can view output from the server by viewing the log at `build/swganh.log`. diff --git a/old/book/installation_windows.rst b/old/book/installation_windows.rst new file mode 100644 index 0000000..d04cf32 --- /dev/null +++ b/old/book/installation_windows.rst @@ -0,0 +1,165 @@ +===================== +Windows Install Guide +===================== + +The most common platform for building and developing SWGANH has been Windows and this chapter covers the easiest way to get started. The SWGANH project is developed on modern technologies and as such has a few minimum version requirements to be mindful about. Most notable is the minimum supported windows version, Vista. + +Installing Build Dependencies +----------------------------- + +The following is a complete list of the 3rd party dependencies that will need to be installed before building the SWGANH source. + +- Microsoft Visual Studio 2012 +- CMake 2.8.7+ +- Git 1.7+ +- Python 3.2 +- Mysql 5.1+ +- SWGANH Dependencies Package +- SWGANH Game Client + +Visual Studio 2012 +~~~~~~~~~~~~~~~~~~~~~~~ + +When installing Visual Studio, make sure to download the Ultimate edition, you can use it for free for 90 days, by that time Microsoft has promised they will release an Express version of Visual Studio 2012. +if you have an MSDN license you should be able to pick up professional or the highest SKU you have access to. + + http://www.microsoft.com/visualstudio/11/en-us/downloads#vs + +CMake 2.8.7+ +~~~~~~~~~~~~ + + +CMake is used to generate the project files for SWGANH source builds. When installing be sure to select the option to add CMake to the PATH. + + http://www.cmake.org/cmake/resources/software.html + +Git 1.7+ +~~~~~~~~ + +Git is used to check out and keep your local source in sync with the latest SWGANH chanages. We recommend installing the GitExtensions package which, in addition to the normal git utilities, provides nice GUI. + +While the Git Extensions package be sure to select the "msysgit" option to install the base Git utilitites. It is also advised that you select the option to add Git GUI and Git Bash to the context menu (right click). This makes it easy to right click on a directory and open the git gui or git bash prompts. + + http://code.google.com/p/gitextensions/downloads/list + +Python 3.2+ +~~~~~~~~~~~ + +Python is used for scripting as well as for generating the SWGANH documentation. After downloading and installing the latest Python 3.2 x86 binaries you will need to add the path to python to the system **PATH**. In a default Python 3.2 install this path is `C:/Python32`. + + http://python.org/download/ + +.. note:: + + Be sure to install the x86 (32bit) binaries and *NOT* the x86-64 (64bit) binaries, it would be bad. + +Mysql 5.1+ +~~~~~~~~~~ + +Mysql is used for database storage in the ANH project. This guide only covers the simplest of installation instructions, other more in-depth topics on database management may be provided in another document in the future. + +To start, download and install the latest Mysql Installer. Select the default developer installation which will provide you with all the tools needed to run and manage the SWGANH database. When the installation is complete you will need to add the path to mysql to the system PATH. In a default mysql installation this is `C:/Program Files/MySQL/MySQL Server 5.5/bin`. + + http://www.mysql.com/downloads/installer/ + +Setting Up the SWGANH Environment +--------------------------------- + +Now it's time to get the SWGANH environment set up and ready to begin building the source. First create a directory to hold all of your SWGANH related files. In this example we will use `C:/workspace` as our base directory. + +SWGANH Dependencies Package +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Windows environment gives us the opportunity to prebuild the libraries that you will need to build the SWGANH source. Download the latest Visual Studio 2012 dependencies from the official SWGANH downloads page and unpack the contents into the workspace directory you created in the previous step. Afterwards, the directory structure should be as follows: `C:/workspace/vendor` + + https://github.com/anhstudios/swganh/downloads + +SWGANH Game Client +~~~~~~~~~~~~~~~~~~ + +The SWGANH Game Client can be installed from the unofficial SWGANH client installer. + + https://github.com/downloads/anhstudios/swganh/anhclient_setup.exe + +.. note:: + + The installer at this time requires a valid Star Wars Galaxies game client installation. In the future there will be an official installer that forgoes this requirement. + +Checkout and Build the Source +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Finally we get to the good stuff! Right click on the swganh workspace directory (e.g. `C:/workspace`) and choose "to open "Git Bash here". Next we'll use git to checkout the latest version of the source. + +:: + + git clone https://github.com/anhstudios/swganh.git + +Run the following commands to generate the project and build the source. + +:: + + mkdir swganh/build + cd swganh/build + cmake -G "Visual Studio 11" .. + cmake --build . + +.. WARNING:: + If you get an error about cmake not being able to find your PYTHON_LIBRARY. re-run the cmake -G command above adding in the following: + cmake -G "Visual Studio 11" -DPYTHON_LIBRARY="LOCATION_TO_PYTHON_DIR/libs" .. + where "LOCATION_TO_PYTHON_DIR" is where your Python32 folder resides. This seems to occur if Python is installed in Program Files x86.. + +This will kick off a full build of the project. The final output can be found at `C:/workspace/swganh/build/bin/Debug`. + +.. note:: + + The Visual Studio solution can be found at `C:/workspace/swganh/build/swganh.sln`. Use this to modify and build changes to existing source files. + +.. note:: + + Since the project files are located outside the source directory adding new files from within visual studio requires changing the default save location. + + To add a new file, manually create it in the src directory and then run the following from within the build directory. + + :: + + cmake .. + +.. note:: + + Documentation can be found in the `C:/workspace/swganh/build/docs/html/Debug` directory. Just open the **index.html** file in your favorite browser. + +Setting up the Database +~~~~~~~~~~~~~~~~~~~~~~~ + +A new database installation is needed before the server can be started for the first time. To install the server navigate to the `C:/workspace/swganh/data/sql` folder and copy the **setup.cfg-example** file to **setup.cfg**. Edit this file with the appropriate login information for the Mysql server you intend to use. + +.. NOTE:: + + Be sure to copy and **NOT** rename the setup.cfg-example file, lest you accidently try to remove it from the source on your next commit. + +.. NOTE:: + + You can use the root user for simple local installations, however, it is advised that you create a dedicated mysql user for your SWGANH installation in production environments. + +Next double click the setup.bat script. This will open up the database installer. Choose option #1 for a complete installation by typing 1 and hitting enter. Once this process completes you can quit the installer. + +Configuring and Running the Server +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You are now entering the home stretch, all that's left is to update the SWGANH configuration and kick off the server. + +Open the `C:/workspace/swganh/build/bin/Debug/config/swganh.cfg` file and edit the following items. First you will need to update the **tre_config** setting with the path to the **live.cfg** file in your SWGANH Game Client directory. + +.. note:: + + Some older SWGANH clients have this file named as **swg2uu_live.cfg**. + +.. warning:: + + Be sure to specify the live.cfg file that is **inside** the SWGANH Game Client directory and **NOT** the one inside the official Star Wars Galaxies directory. + +Second, update the mysql database connection information with the address and user you used to setup the database in the previous section. + +Finally, set the address in the **service.connection** section to your public facing IP and then save and close the file. + +You can now kick off the server by running the **swganh.exe** at `C:/workspace/swganh/build/bin/Debug/swganh.exe`. diff --git a/old/book/map.rst.inc b/old/book/map.rst.inc new file mode 100644 index 0000000..6b1b21f --- /dev/null +++ b/old/book/map.rst.inc @@ -0,0 +1,6 @@ +* :doc:`/book/installation` +* :doc:`/book/architecture` +* :doc:`/book/services` +* :doc:`/book/plugins` +* :doc:`/book/events` +* :doc:`/book/scripting` diff --git a/old/book/plugins.rst b/old/book/plugins.rst new file mode 100644 index 0000000..0b81e80 --- /dev/null +++ b/old/book/plugins.rst @@ -0,0 +1,7 @@ +======= +Plugins +======= + +In order to add a large amount of customizability and flexibility within the SWGANH server. The developers have decided to utilize the idea of loading in objects dynamically. This allows custom plugins to be created that tweaks functionality, utilizes a different data source, and more just with a simple tweak in the configuration file. + +The plugin system provides a way to register how to create and destroy objects and then it uses registrations to create new objects on the fly. This registration is then available to the server at runtime and allows a quick and easy method to get objects as needed. diff --git a/old/book/scripting.rst b/old/book/scripting.rst new file mode 100644 index 0000000..5c942b7 --- /dev/null +++ b/old/book/scripting.rst @@ -0,0 +1,13 @@ +========= +Scripting +========= + +General Overview +~~~~~~~~~~~~~~~~ + +The SWGANH project uses `Python 3.x `_ for in game scripting. The most obvious area where scripting is used is within the in-game commands. Almost everything in SWG is a command, and they can all be processed through scripting. SWGANH has chosen Python as the preferred scripting language because of it's robustness, ease of use, and overall performance. Another reason is because the great C++ integration with the `Boost.Python `_ library. This allows us to have very nice integration with Python from C++ and vice versa. + +Why did SWGANH decide to use Scripting? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SWGANH uses scripting for ease of use and flexibility in game features. +What this means is that anyone who decides to use SWGANH can expect the ability to easily add, remove, and tweak gameplay with minimal changes to the core application of SWGANH. This is something that was needed as SWGANH is first and foremost a platform for communities to gather around and build the Star Wars Galaxies game they have always wanted. While the base of the game is centered around Patch 14.1 (Pre-CU) we believe this allows for the highest amount of flexibility and overall generally enjoyment. diff --git a/old/book/services.rst b/old/book/services.rst new file mode 100644 index 0000000..962fba3 --- /dev/null +++ b/old/book/services.rst @@ -0,0 +1,7 @@ +======== +Services +======== + +Services are systems that are available the entire lifetime of the application. They also generally handle interactions directly with the SWG Protocol and they expose an API for controlling or accessing data that covers a feature set that can be used by all other services. + +Services are generally broken up into game system categories, but they can also be more generic than that. For example there is a Login Service that handles all of the interaction between the Client Login Messages, the database and server itself. This service handles these messages and allow you to do what is necessary with the data. In most cases, this involves interacting with the database and sending a SWG Protocol Message reply back to the Client. Most services follow this basic pattern, but they are not restricted to it. diff --git a/old/conf.py.in b/old/conf.py.in new file mode 100644 index 0000000..a5cdf24 --- /dev/null +++ b/old/conf.py.in @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +# +# SWG:ANH documentation build configuration file, created by +# sphinx-quickstart on Thu Aug 18 19:24:10 2011. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('@SWGPY_DIR@/@configuration@')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.inheritance_diagram', 'sphinx.ext.graphviz'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'SWGANH' +copyright = u'2012, ANH Studios' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '@swganh_VERSION@' +# The full version, including alpha/beta/rc tags. +release = '@swganh_VERSION@' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = '@SPHINX_THEME@' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = ['@SPHINX_THEME_DIR@'] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'SWGANHdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'SWGANH.tex', u'SWG:ANH Documentation', + u'ANH Studios', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'swganh', u'SWGANH Documentation', + [u'ANH Studios'], 1) +] diff --git a/old/contributing/index.rst b/old/contributing/index.rst new file mode 100644 index 0000000..27e8fb9 --- /dev/null +++ b/old/contributing/index.rst @@ -0,0 +1,14 @@ +Contributing +============ + +.. toctree:: + :hidden: + + issues + pull_requests + tests + security + standards + license + +.. include:: /contributing/map.rst.inc diff --git a/old/contributing/issues.rst b/old/contributing/issues.rst new file mode 100644 index 0000000..e8a2127 --- /dev/null +++ b/old/contributing/issues.rst @@ -0,0 +1,32 @@ +================== +Reporting an Issue +================== + +If you find a bug or have any problems with the SWGANH server please report it. This helps us to make the SWGANH server as enjoyable to play on as possible. + +.. note:: + + If you think you've found a security issue, please use the special + :doc:`procedure ` instead. + +Before you create a new issue: + +* Consult the `documentation`_ to ensure you're using the SWGANH engine properly. +* Ask for assistance on the `forum`_ or on the #swganh `IRC channel`_ if you're unsure whether or not the problem you're having is a bug. + +If you have a bug use the `Issues tool`_ found at the official `SWGANH repository`_: + +* Use the title field to clearly describe the issue; + +* Describe the steps needed to reproduce the bug with short code examples + (providing a unit test that illustrates the bug is best); + +* Give as much details as possible about your environment (OS, Compiler Version, SWGANH Version, enabled plugins, ...); + +* *(optional)* Attach a :doc:`pull request `. + +.. _documentation: http://swganh.com/docs/ +.. _forum: http://swganh.com/forums/ +.. _IRC channel: irc://irc.freenode.net +.. _Issues tool: https://github.com/anhstudios/swganh/issues +.. _SWGANH repository: https://github.com/anhstudios/swganh \ No newline at end of file diff --git a/old/contributing/license.rst b/old/contributing/license.rst new file mode 100644 index 0000000..92e42a3 --- /dev/null +++ b/old/contributing/license.rst @@ -0,0 +1,16 @@ +============== +SWGANH License +============== + +SWGANH is released under the MIT license. + +The License +~~~~~~~~~~~ + +Copyright (c) 2011-2012 ANH Studios + +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. \ No newline at end of file diff --git a/old/contributing/map.rst.inc b/old/contributing/map.rst.inc new file mode 100644 index 0000000..c920fa7 --- /dev/null +++ b/old/contributing/map.rst.inc @@ -0,0 +1,7 @@ +* :doc:`/contributing/issues` +* :doc:`/contributing/pull_requests` +* :doc:`/contributing/tests` +* :doc:`/contributing/security` +* :doc:`/contributing/standards` +* :doc:`/contributing/license` + \ No newline at end of file diff --git a/old/contributing/pull_requests.rst b/old/contributing/pull_requests.rst new file mode 100644 index 0000000..1ec4998 --- /dev/null +++ b/old/contributing/pull_requests.rst @@ -0,0 +1,152 @@ +========================= +Submitting a Pull Request +========================= + +The SWGANH team accepts code contributions via the GitHub Pull Request system. This allows us a tight integration with our issue tracking functionality as the two are often heavily entwined. + +To submit a patch first you will need to get and build the SWGANH source code: + +* Create and sign into a `GitHub`_ account. +* Fork the `SWGANH repository`_ by clicking the "**Fork**" button. +* After the forking process has completed, clone your fork: + +.. code-block:: bash + + $ git clone git@github.com:USERNAME/swganh.git + +* Add the official SWGANH repository as a remote named upstream: + +.. code-block:: bash + + $ cd swganh + $ git remote add upstream https://github.com/anhstudios/swganh.git + +* Build the code using the :doc:`official install guide `. + +Working on a Pull Requests +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Every pull request you create for a bug fix or new feature needs its own topic branch. + +.. note:: + + Until we reach a 1.0 release, all pull requests should be directed to the **develop** branch. + +Create a topic branch with the following command: + + git checkout -b BRANCH_NAME develop + +.. tip:: + + Use descriptive names for your topic branches. Pull requests that fix a particular issue should be named issue/XXX where XXX is the issue number. Branches for new features should be named with a feature/ prefix (e.g., feature/guild_system). + +The above will switch your working directory to the newly created branch. You are now ready to begin working on your issue or feature. Keep the following points in mind while working on code. + +* Follow the :doc:`coding standards `. +* If possible, add unit tests to prove that the bug is fixed or that the feature works as specified. +* Commit often and use good commit messages. + +Submitting a Pull Request +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Before you submit a pull request make sure to pull in the latest changes from the main develop line. This is especially important for long running feature additions. + +.. code-block:: bash + + $ git checkout develop + $ git fetch upstream + $ git merge upstream/develop + $ git checkout BRANCH_NAME + $ git rebase develop + +While running a ``rebase`` you may encounter merge conflicts. Use the ``git status`` command to see the unmerged files. Resolve all of the conflicts and then continue on with the rebase: + +.. code-block:: bash + + $ git add ... # add resolved files + $ git rebase --continue + +Check that all :doc:`tests ` pass and then push your branch to your GitHub repository: + +.. code-block:: bash + + $ git push origin BRANCH_NAME + +You can now discuss your branch on the `SWGANH IRC`_ or the `forums`_. When you are ready you can make a pull request from your GitHub page using the **Pull Request** button. + +Your pull request may generate feedback that requires additional work to your topic branch before it can be merged into the main development line. When pushing the requested changes back up to your GitHub repository be sure to rebase and not merge; then force the push back to origin: + +.. code-block:: bash + + $ git rebase -f upstream/master + $ git push -f origin BRANCH_NAME + +.. warning:: + + Always specify the branch name explicitly when doing a push -f (or --force) to avoid causing issues with other branches. + +Sometimes you may be asked to "squash" your commits. This is common when there are a number of similar changes to many files. Squashing commits will turn many commits into a single commit. Squashing is accomplished via ``rebase``: + +.. code-block:: bash + + $ git rebase -i head~3 + +The number 3 here must equal the amount of commits in your branch. After running this command a text editor will pop up and display a list of commits: + +:: + + pick 1a31be6 first commit + pick 7fc64b4 second commit + pick 7d33018 third commit + +To squash all commits into the first one, remove the word "pick" before the second and last commits and replace it with the word "squash" or just "s". When you save git will start rebasing and once complete will ask you to enter a new commit message (by default this is set to a listing of messages from all the commits). When finished execute the push command. + +.. code-block:: bash + + $ git push -f origin BRANCH_NAME + + +Testing Pull Requests +~~~~~~~~~~~~~~~~~~~~~ + +Members of the testing team have a vital role to play in ensuring that all the code going into the official development line is up to par. This involves testing contributed bug fixes or even brand new features from the core development team or from coders in the community. + +In order to begin testing make sure you already have a SWGANH environment :doc:`installed `. Before each round of testing make sure that you have the latest changes from the official repository. + +.. code-block:: bash + + $ git checkout develop + $ git fetch upstream + $ git merge upstream/develop + +Next it's time to find a Pull Request to review, these are listed at https://github.com/anhstudios/swganh/pulls. After clicking on a pull request you can identify the user that made the request and the branch they want pulled from. + +.. image:: /images/contributing/pull_requests_image_1.png + :align: center + +In the case of the example above the user is **dead1ock** who wants someone to merge in the **feature/spatial_indexing** branch. + +The first time that you test a pull request from a contributor you will need to add them as a remote so that you can fetch their changes. Note that this only needs to be completed the first time you test a pull request from a new contributor. + +.. code-block: bash + + # following the example above the USERNAME would be replaced with dead1ock + $ git remote add USERNAME git://github.com/USERNAME/swganh.git + +With the contributor's remote added its now time to pull in their code and build it. + +.. code-block: bash + + $ git fetch USERNAME + $ git checkout PULL_REQUEST_BRANCH + $ cd build + $ cmake .. + $ cmake --build . + +Replace **PULL_REQUEST_BRANCH** with the name identified from the pull request, in the example above this would be the **feature/spatial_indexing** branch. + +.. _GitHub: http://github.com +.. _SWGANH repository: http://github.com/anhstudios/swganh +.. _SWGANH IRC: irc://irc.swganh.org +.. _forums: http://swganh.com/forums + diff --git a/old/contributing/security.rst b/old/contributing/security.rst new file mode 100644 index 0000000..8fa3550 --- /dev/null +++ b/old/contributing/security.rst @@ -0,0 +1,19 @@ +Reporting a Security Issue +========================== + +Found a security issue in SWGANH? Don't use the forums or the issue tracker. All security issues must be sent to **security [at] +swganh.com** instead. Emails sent to this address are forwarded to +the SWGANH core-team private mailing-list. + +For each report, we first try to confirm the vulnerability. When it is +confirmed, the core-team works on a solution following these steps: + +1. Send an acknowledgement to the reporter; +2. Work on a patch; +3. Write a post describing the vulnerability, the possible exploits, and how to patch/upgrade affected applications; +4. Apply the patch to all maintained versions of SWGANH; +5. Publish the post on the official SWGANH blog. + +.. note:: + + While we are working on a patch, please do not reveal the issue publicly. \ No newline at end of file diff --git a/old/contributing/standards.rst b/old/contributing/standards.rst new file mode 100644 index 0000000..8f114e4 --- /dev/null +++ b/old/contributing/standards.rst @@ -0,0 +1,62 @@ +Coding Standards +================ + +These are a list of things to keep in mind, check for and apply to code you're writing for the SWG:ANH application. Keeping to this will help make it easier for everyone who works on the codebase to identify what is going on in the code you've written. These are also points that all reviewers should be applying to incoming code before it hits the develop line. Sharing these changes back with the developer is vital to improving everyone's common working knowledge. + +.. note:: When going through code it's very, very tempting to start applying this to everything, including sections outside the area you are currently giving attention to or reviewing. Do not give into this temptation as it will lead off into unknown territory and also cause the diffs to be even more crazy than normal. All code will get it's time in the light, be patient and stay the course because it's slow and steady that wins this race. + +Follow the agreed upon style guide +---------------------------------- + +When writing source or accepting it in ensure that it fits with the agreed upon style guide, a variation of the `Google C++ Style Guide`_. The following are where the ANH guide deviates from above: + +* Exceptions are allowed +* C++0x libraries are allowed (and encouraged) +* Enums must be ALL_CAPS_WITH_UNDERSCORES +* Non accessor/mutator functions should be camel case starting with a lower case, non-numeric character +* Documenting comments in headers should follow the Doxygen format +* Indent by 4 spaces instead of 2 +* No indentation before public, protected, private + +Order includes appropriately +---------------------------- + +See the Google C++ Style Guide `section`_ on this topic for further information on the how and why behind this item. + +Prefer standard algorithms to hand-written loops +------------------------------------------------ + +Hand written loops are often more verbose and slower than solutions that use the standard library algorithms, particularly when given the addition of lambdas in the latest standard. Always keep a copy of the `latest standard`_ handy, particularly section 25 on the Algorithms library. + +When you come up against a hand crafted loop consider: + +* What does this loop currently do? + + It is important when reviewing a piece of code to truly understand what it is currently doing. When looking at a fresh piece of code this is the most objective question to ask and should be the first one asked. + +* What is it trying to achieve? + + With an understanding of what the code is actually doing take a step back and look at what the code is doing in the context of the surrounding code and ask: What problem was the original author trying to solve? Compare the answer to this with what the code is currently doing. If they do not match roll up those sleeves and get to cleaning! + +* Can the intention and execution be improved by using a standard algorithm? + + How hard was identifying the intention and behavior of the code? If it was difficult to infer what the code was doing from a simple reading chances are it needs to be refactored. Consult the standard's algorithm section to see if there are any solutions to help. + +Simplify overly verbose logic +----------------------------- + +Take the time to fully understand the purpose of any function/method you are currently looking at. Once you know why it exists take a closer look at how the problem was originally solved. Often times our legacy code was written on code binges where constant tweaks were made to get things working and then never reviewed before making it into the main source line. There are many places still where hundreds of lines of code can be shrunk to tens of lines (or less). + +Add missing API documentation +----------------------------- + +Before the start of this initiative there existed almost no API documentation. In order to change this and build up a useful base of documentation whenever entering into an existing function/method take the time to understand what it's purpose is and then add a Doxygen style doc above its declaration. + +Remove commented sections of code +--------------------------------- + +If code shouldn't be there, remove it. Don't comment on how silly it is and leave it there as a testimony to the ignorance of others... nobody really cares. Just remove the code and clean up our source. And don't worry about losing any information, our projects and all their history are always available thanks to Git, just browse a files history to see its previous states. + +.. _`Google C++ Style Guide`: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml +.. _`section`: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Names_and_Order_of_Includes#Names_and_Order_of_Includes +.. _`latest standard`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf \ No newline at end of file diff --git a/old/contributing/tests.rst b/old/contributing/tests.rst new file mode 100644 index 0000000..356ad78 --- /dev/null +++ b/old/contributing/tests.rst @@ -0,0 +1,38 @@ +============ +Code Testing +============ + +Before submitting a :doc:`pull request`, you need to run the SWGANH test suite to check that your changes have not broken any existing code. + +Running the Test Suite with Visual Studio +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To run the test suite in Visual Studio first open the project and then right click on the "RUN TESTS". + +Running the Test Suite from the Command Line +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To run the test suite from the command line first build the project. + +.. code-block:: bash + + $ cmake --build . + +Next run the test suite: + + $ ctest -C Debug + +Creating New Tests +~~~~~~~~~~~~~~~~~~ + +To create a new test first create a file to store the test in. All test files must be suffixed with ``_unittest.cc`` or ``_unittest.h``. Next create your test according to the `googletest`_ documentation. + +Finally, re-run the cmake command to generate the test project and then re-build and test the project: + +.. code-block:: bash + + $ cmake .. + $ cmake --build . + $ ctest -C Debug + +.. _googletest: http://code.google.com/p/googletest/wiki/Primer diff --git a/old/cookbook/index.rst b/old/cookbook/index.rst new file mode 100644 index 0000000..3d9dfec --- /dev/null +++ b/old/cookbook/index.rst @@ -0,0 +1,13 @@ +Cookbook +======== + +.. toctree:: + :hidden: + + plugins/best_practices + + scripting/command_scripts + + security/custom_authentication + +.. include:: /cookbook/map.rst.inc diff --git a/old/cookbook/map.rst.inc b/old/cookbook/map.rst.inc new file mode 100644 index 0000000..c5e0b06 --- /dev/null +++ b/old/cookbook/map.rst.inc @@ -0,0 +1,11 @@ +* **Plugins** + + * :doc:`/cookbook/plugins/best_practices` + +* **Scripting** + + * :doc:`/cookbook/scripting/command_scripts` + +* **Security** + + * :doc:`/cookbook/security/custom_authentication` diff --git a/old/cookbook/plugins/best_practices.rst b/old/cookbook/plugins/best_practices.rst new file mode 100644 index 0000000..87f9c5c --- /dev/null +++ b/old/cookbook/plugins/best_practices.rst @@ -0,0 +1,48 @@ +.. index:: + single: Plugins; Best Practices + +Plugin Structure and Best Practices +=================================== + +The SWG:ANH plugin system has been designed to be easy to use and simple to +adapt to most situations. While creating a new plugin is not difficult, +following a few best practices will make things easier for the future +maintainers of your plugin (including yourself!). + + +Directory Structure +------------------- + +.. code-block:: text + + XXX/... + my_plugin/ + CMakeLists.txt + LICENSE + main.cc + resources/ + config/ + my_plugin.cfg.dist + doc/ + index.rst + scripts/ + +The ``XXX`` directory(ies) reflects the namespace structure of the plugin. + +The following files are mandatory: + +* ``CMakeLists.txt``: Describes how to build the plugin; +* ``main.cc``: Entry-point for the plugin; +* ``LICENSE``: The full license for the plugin code; +* ``resources/config/my_plugin.cfg.dist``: The default configuration file for your plugin; +* ``resources/doc/index.rst``: The root file for the plugin documentation. + +Python scripts/modules used by your plugin should be placed under the +``resources/scripts`` directory to ensure they are installed in the proper +location after building. + +.. note:: + + These rules are in place to ensure that the build system and other 3rd party + tools can rely on this default structure to perform their work. + diff --git a/old/cookbook/scripting/command_scripts.rst b/old/cookbook/scripting/command_scripts.rst new file mode 100644 index 0000000..9fd4cbc --- /dev/null +++ b/old/cookbook/scripting/command_scripts.rst @@ -0,0 +1,372 @@ +Creating a New Command Script +============================= + +This will take you step by step on how to create a simple command script for SWGANH. +This assumes that you have followed the server setup instructions and it is working as expected. + +For this yeaexample I will be doing a very simple command, but one that has interaction with another player. +`Add Friend `_ + +Step 1 - Startup +~~~~~~~~~~~~~~~~ + +Add the script reference to the command table in the galaxy database. +Open up your favorite mysql editor program, edit the 'command' table and look for the script_hook column. +Here we are going to be putting in the location of our python script that we have yet to create. +In this case we are going to put 'scripts/commands/add_friend.py' into the script hook for the addFriend row. + +Step 2 - Basic Script +~~~~~~~~~~~~~~~~~~~~~ + +Now that this is done we can create our script. Open up your favorite python editor (I just use notepad++) +We know based on our documentation located `Here ` _ +That we want to use the 'add_friend' function in the Player class. + +.. NOTE:: + + The way the SWG hierarchy works is that `Player `_ is a seperate object than `Creature `_ + This means that the normal actor will not work to add a friend, we will need to get the `Player `_ somehow. + This is done through another function `get_player `_, this will return the player object and then we can continue. + +our script now looks like this... + +.. code-block:: py3 + + import swgpy.object + + # Get the player object + player = actor.get_player() + target_player = creature_target.get_player() + # Make sure the player object and the target exists + if player and target_player: + # Check if the player target is already in our friends list + if not player.is_friend(target_player.id): + player.add_friend(target_player.id) + actor.ObjectController().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_added', swgpy.ProseType.TT, target.id), False, False) + elif: + actor.ObjectController().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_duplicate', swgpy.ProseType.TT, target.id), False, False) + elif: + actor.ObjectController().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_not_found', swgpy.ProseType.TT, target.id), False, False) + +A couple of things to note here + +Number one is that we are getting both the player and the target player objects, and if these don't exist we display a message. +To determine which messages to send out, I used the `SWG String Search `_ and searched for 'friend_added' +Secondly we are using the ObjectController to send the message to the actor to let them know the target was either added or not. +We used ProseType of TT, as that's what is shown in the `SWG String Search `_ and passed it the 'target id of the creature' +The two False at the end just tell SendSystemMessage that we want to show it not just in the chatbox (also in the middle of the screen) and to only send it to the current actor. + +Step 3 - First Example Finished? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Lets save our script as add_friend.py in the data/scripts/commands folder +Build our server again (this will copy over the scripts from data/commands to bin/Debug/commands (if on Windows) +Then, we should be able to run our server and the command should execute as expected. + +You are done with your first simple example! + +Step 4 - Troubleshooting +~~~~~~~~~~~~~~~~~~~~~~~~ + +Or are you? The great thing about Python is you are able to tweak the script at runtime and see the results immediately during the next script run. +My first run through for example I got a somewhat cryptic message in the server console output + +:: + + Python error: + SyntaxError: (`invalid syntax`, (``, 12, 6, `\telif:\n`)) + +Woah... what does this all mean? Python lets us know that it didn't like our script and something is definitely wrong here. +Lets break it up piece by piece. + +*SyntaxError* This means python couldn't execute a particular line because it didn't know how to interpret it. +*12, 6* This is saying the error is on line 12 and in position 6 +*`\telif:\n`* +Well that narrows it down pretty well for us, we know that line 12, we have a tab indentation and an elif: and a newline, which is what the \t and \n are respectively +This tells me that it is most likely a formatting error, or elif is not the correct syntax in this case. +In reality this is me just making a dumb mistake, I realize that I should be using else: instead of elif: as elif is used for +Once i replace the elif with else: +I get a different error, saying NoneType does not have method get_player +The problem here is that our creature_target doesn't exist. I need to re-look at how add_friend is supposed to work... +It looks like it just simply uses a name as a parameter. + +Step 5 - Down the Rabbit Hole +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Since this is the first social kind of command added to the game we are going to have to do more work than expected. +We will need to create a new service that is going to allow us to interact with the database, and interact with the player itself. + +Lets start creating our new service. Go into swganh/src/ and I will create a new folder called 'social' +I need to create some files in here. I know I want to have a 'service' so I will create social_service.h and social_service.cc +I will also create a social_service_binding.h and social_service_binding.cc and a CMakeLists.txt +This should be all I need initially to get this service going. + +For CMakeLists.txt I copied it from an existing service and changed the name to 'social' That's really all I need to do for that. +We also need to open up CMakeLists.txt in src/swganh and put in the following: +add_subdirectory(social) + +This will allow our build system to recognize there is another CMakeLists.txt in the social folder and the parse it out accordingly. + +Step 6 - Services In Depth +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We need to take a step back here and really go over what a service is in the context of swganh and why we should be creating one. +Services are generally available the entire lifetime of the server. They can handle SWG Protocols and expose APIs for controlling/accessing data +that covers a feature set that is orthogonal to all other services. +This means that the service is available as long as the Server is operational, it exposes some functionality to other services and/or scripts. + +Perect, this sounds like what we want. We want a service that is able to pull data from the database, have that data available the entire life of the server, +and we want to allow other services access to this data. + +Step 7 - Service Integration and Playing with Data +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We have our existing social_service files and social_service_binding files, these are probably empty, so let's get these filled in. +Lets start with social_service.h + +As a header file, this describes what we are going to be doing with our service. Based on our services we can see that this service +is going to inherit from swganh::base::BaseService. Our code looks little like this *snippet* + +.. code-block:: c + + class SocialService : public swganh::base::BaseService + { + public: + explicit SocialService(swganh::app::KernelInterface* kernel); + + swganh::service::ServiceDescription GetServiceDescription(); + }; + +This sets up a very very basic structure, all we are doing here is just getting the service created, we will flesh it out later. +Lets just do the same for the .cc file + +.. code-block:: c + + SocialService::SocialService(KernelInterface* kernel) + : BaseService(kernel) + {} + + ServiceDescription SocialService::GetServiceDescription() + { + ServiceDescription service_description( + "SocialService", + "social", + "0.1", + "127.0.0.1", + 0, + 0, + 0); + + return service_description; + } + +Ok, basic structure is in place. +Let's get enough just to set up our friends list. +We know we will need to have a function that is called AddFriend takes in a Player object and a string as parameters and returns a true or false, if the player was found or not. +so lets do that... + +.. code-block:: c + + bool SocialService::AddFriend(const shared_ptr& player, const string& friend_name) + { + return true; + } + +Right now our function does nothing and just returns true. +What we want to do is build out a simple interface as we know that this social service will end up doing a lot more than just adding a friend. +We know that we need to interact with the database and get some data, we can and should do this using a plugin. More about plugins and how they interact `HERE <>_` + +Step 8 - Setting up the Database Provider and Interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The provider interface is a pretty common pattern in our codebase, so lets do what we usually do and take a look at an example. in swganh/character/character_provider_interface.h +we can see a very similar thing to what we will need to do. In fact actually it looks like what we really want to do is just add to the character_provider_interface a function +that will perform the required action. What we really want is a way to look up a character name to see if they exist, this sounds just like something the character provider should do for us. + +Lets open the character_provider_interface.h and add a few lines. + +.. code-block:: c + + virtual uint64_t GetCharacterIdByName(const std::string& name) = 0; + +Ok, now we need to update the existing mysql_character plugin to take into consideration this change. + +our mysql_character_provider.h has added this. + +.. code-block:: c + + virtual uint64_t GetCharacterIdByName(const std::string& name); + +and our mysql_character_provider.cc has filled in the details for this function. + +.. code-block:: c + + uint64_t MysqlCharacterProvider::GetCharacterIdByName(const string& name) + { + uint64_t character_id = 0; + try { + auto conn = kernel_->GetDatabaseManager()->getConnection("swganh_galaxy"); + auto statement = std::unique_ptr( + conn->prepareStatement("SELECT id FROM object where custom_name like ? and type_id = ?;") + ); + statement->setString(1, name + '%'); + statement->setUInt(2, swganh::object::Player::type); + auto result_set = std::unique_ptr(statement->executeQuery()); + while(result_set->next()) + { + character_id = result_set->getUInt64(1); + } + + } catch(sql::SQLException &e) { + LOG(error) << "SQLException at " << __FILE__ << " (" << __LINE__ << ": " << __FUNCTION__ << ")"; + LOG(error) << "MySQL Error: (" << e.getErrorCode() << ": " << e.getSQLState() << ") " << e.what(); + } + return character_id; + } + +Now lets set up the interaction with the character provider plugin and see what this looks like. + +.. code-block:: c + + bool SocialService::AddFriend(const shared_ptr& player, const string& friend_name) + { + uint64_t friend_id = character_provider_->GetCharacterIdByName(friend_name); + /// If we found our friend, lets add them to our friends list (which will get updated by the player) + if (friend_id > 0) + { + player->AddFriend(friend_name); + // This persists the player object immediately. + kernel()->GetServiceManager()->GetService + ("SimulationService")->PersistObject(player->GetObjectId()); + + return true; + } + + return false; + } + +That is quite easy to follow and very modular, we can change what we are using to actually get the Character Id without having to rework this code. +This is a huge advantage of interfaces and why you see them in our codebase so frequently. Please check out the full social_service.h and .cc for more details. + +Step 9 - Registering the Service +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now that we have a service created and compiling, we can add it to our server startup process. +Lets open up swganh_app.cc this is quite a large file and really does a lot of the work of starting up the game server. +first we need to 'include' our file that we created, so the swganh app knows about it. +#include "swganh/social/social_service.h" + +Next lets go down to where all the other services are loaded: LoadCoreServices. + +Lets add this in under the last service there: + +.. code-block:: c + + kernel_->GetServiceManager()->AddService( + "SocialService", + make_shared(kernel_.get())); + +Now we'll build the server, all should be good. + +Step 10 - Setting up bindings +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now that we've created a very simple service with a very simple API, we want to expose this to Python to use in our script. +We do this through a process called binding. Fortunately most of the hard work is done for us with Boost.Python +All we need to do is tell Boost.Python about our service and it will automatically create a module for us. +Lets see what that looks like now. This is social_service_binding.h + +.. code-block:: c + + #include "swganh/python_shared_ptr.h" + #include "social_service.h" + + #include + + using namespace swganh::social; + using namespace boost::python; + using namespace std; + + void exportSocialService() + { + class_, boost::noncopyable>("SocialService", "The social service handles services that involve social actions", no_init) + .def("add_friend", &SocialService::AddFriend, "Checks the database to see if the character name exists and then adds the friend to the player") + ; + } + +As you can see this is a very simple example, we are using Boost.Python to basically create a python module which describes this C++ class and methods. +Most services are going to be very similar to this, so this is a good template to go off. +As you can see we have added in our 'AddFriend' method, this is to be expose to python as "add_friend" + +There is just one more step in order for this binding to work properly... +We need to now add a way to get to this service. This is done in the ANH Core through a system called the Service Manager. +Luckily we have an example to pull from on how to expose a service through this. +We will be opening up swganh_kernel_binding.h in app_binding. + +This will be used to expose all services out to Python. We will be using the SimulationService as an example to copy from. + +.. code-block:: py3 + + class_("ServiceManager", "provides an interface to common services", no_init) + .def("simulation_service", make_function( + bind(&swganh::service::ServiceManager::GetService, std::placeholders::_1, "SimulationService"), + default_call_policies(), + boost::mpl::vector, swganh::service::ServiceManager*>()), + "returns an internal refrence of the :class:`.SimulationService`") + +This is actually pretty complicated code and there is a lot of magic going on behind the scenes, but all we need to know is that we are exposing the +service to python as a shared_ptr. We can literally replace simulation with social and this will work as expected. + +Step 11 - Back to the script! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ok, so now we know that we need to use the social service that we set up to add a friend. We also know through our documentation that we can +get to services through the :class:`.SWGKernel` service_manager +So lets add that call in the script after we check to see if the name is already in our friends list. +Next we need to send the player a message if the command succeeded or not. From the documentation again, we see that in order to send messages to the client +we need to get the Controller of the object and send a message. +The syntax is this + +.. code-block:: py3 + + actor.Controller().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_added', swgpy.ProseType.TT, friend_request_name), False, False) + +This is telling the code to get the controller object, invoke the SendSystemMessage using it's OutOfBand constructor that we are building right into the command. +We are telling it that it's a TT ProseType type, which we can see by looking `SWG Strings cmnty `_ +This fits right in with what the Strings message says we want to do. +Building out our script a little more it now looks like this + +.. code-block:: py3 + + import re, swgpy.object + + split = re.split('\W+', command_string) + friend_request_name = split[0] + print(friend_request_name) + # Get the player object + player = actor.get_player() + if player: + # Check if the name is already in our friends list + if not player.is_friend(friend_request_name): + added = kernel.service_manager().social_service().add_friend(player, friend_request_name) + if added: + print(added) + actor.Controller().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_added', swgpy.ProseType.TT, friend_request_name), False, False) + else: + print(added) + actor.Controller().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_not_found', swgpy.ProseType.TT, friend_request_name), False, False) + else: + print(added) + actor.Controller().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_duplicate', swgpy.ProseType.TT, friend_request_name), False, False) + else: + print('Player object not found for object id' + actor.id) + +And we run it in our server and now we get a response, saying that our friend was added (if he exists on the server)! + +There are more things to keep in mind such as checking the ignore list, checking to see if the added friend is online and sending a message update. +This example will not cover those scenarios but you can check them out in the existing add_friend.py script. + +This example was more of a step by step process that followed MY particular though pattern. There can be other ways of doing things, I just +hope this was helpful. For any particular or in-depth questsions, please hit us up on IRC@ irc.swganh.com #swganh + +~Kyle Craviotto \ No newline at end of file diff --git a/old/cookbook/security/custom_authentication.rst b/old/cookbook/security/custom_authentication.rst new file mode 100644 index 0000000..21eda77 --- /dev/null +++ b/old/cookbook/security/custom_authentication.rst @@ -0,0 +1,14 @@ +.. index:: + single: Login; Custom Authentication + +How to customize account authentication +======================================= + +The SWG emulator scene has had a number of various communities spring up around +over the years, many of which plan on running their own Galaxy once there is a +project far enough along to sustain an economy. Chances are, if you're managing +one of these communities, you already have a forum or some other community +portal application with account credentials for each of your players. This +Cookbook entry shows you how to create a plugin that uses the account +credentials from a phpBB3 forum for the Login server authentication. + diff --git a/old/images/contributing/pull_requests_image_1.png b/old/images/contributing/pull_requests_image_1.png new file mode 100644 index 0000000000000000000000000000000000000000..98c4511cae73e95f96d2e8b16d2c507baf94ca42 GIT binary patch literal 27759 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 + + + $(SolutionDir)html\$(Configuration)\index.html + WebBrowserDebugger + + + WebBrowserDebugger + $(SolutionDir)html\$(Configuration)\index.html + + \ No newline at end of file From 3e882a3d7c5d8a58229cddcdf777e8e858104b0d Mon Sep 17 00:00:00 2001 From: Indota Date: Tue, 24 Sep 2013 23:01:27 -0400 Subject: [PATCH 4/9] Clearing Root --- .gitignore | 2 - CMakeLists.txt | 93 ----- book/architecture.rst | 11 - book/events.rst | 33 -- book/index.rst | 14 - book/installation.rst | 17 - book/installation_client.rst | 3 - book/installation_docs.rst | 70 ---- book/installation_linux.rst | 176 --------- book/installation_windows.rst | 165 -------- book/map.rst.inc | 6 - book/plugins.rst | 7 - book/scripting.rst | 13 - book/services.rst | 7 - conf.py.in | 216 ---------- contributing/index.rst | 14 - contributing/issues.rst | 32 -- contributing/license.rst | 16 - contributing/map.rst.inc | 7 - contributing/pull_requests.rst | 152 ------- contributing/security.rst | 19 - contributing/standards.rst | 62 --- contributing/tests.rst | 38 -- cookbook/index.rst | 13 - cookbook/map.rst.inc | 11 - cookbook/plugins/best_practices.rst | 48 --- cookbook/scripting/command_scripts.rst | 372 ------------------ cookbook/security/custom_authentication.rst | 14 - images/contributing/pull_requests_image_1.png | Bin 27759 -> 0 bytes index.rst | 28 -- pythonapi/command.rst | 18 - pythonapi/creature.rst | 83 ---- pythonapi/index.rst | 13 - pythonapi/kernel.rst | 16 - pythonapi/map.rst.inc | 6 - pythonapi/object.rst | 7 - pythonapi/object_controller.rst | 14 - pythonapi/objects.rst | 11 - pythonapi/player.rst | 39 -- pythonapi/services.rst | 73 ---- pythonapi/tangible.rst | 6 - pythonapi/utility.rst | 7 - tools/cmake/FindSphinx.cmake | 37 -- tools/windows/user_project.vcxproj.in | 11 - 44 files changed, 2000 deletions(-) delete mode 100644 .gitignore delete mode 100644 CMakeLists.txt delete mode 100644 book/architecture.rst delete mode 100644 book/events.rst delete mode 100644 book/index.rst delete mode 100644 book/installation.rst delete mode 100644 book/installation_client.rst delete mode 100644 book/installation_docs.rst delete mode 100644 book/installation_linux.rst delete mode 100644 book/installation_windows.rst delete mode 100644 book/map.rst.inc delete mode 100644 book/plugins.rst delete mode 100644 book/scripting.rst delete mode 100644 book/services.rst delete mode 100644 conf.py.in delete mode 100644 contributing/index.rst delete mode 100644 contributing/issues.rst delete mode 100644 contributing/license.rst delete mode 100644 contributing/map.rst.inc delete mode 100644 contributing/pull_requests.rst delete mode 100644 contributing/security.rst delete mode 100644 contributing/standards.rst delete mode 100644 contributing/tests.rst delete mode 100644 cookbook/index.rst delete mode 100644 cookbook/map.rst.inc delete mode 100644 cookbook/plugins/best_practices.rst delete mode 100644 cookbook/scripting/command_scripts.rst delete mode 100644 cookbook/security/custom_authentication.rst delete mode 100644 images/contributing/pull_requests_image_1.png delete mode 100644 index.rst delete mode 100644 pythonapi/command.rst delete mode 100644 pythonapi/creature.rst delete mode 100644 pythonapi/index.rst delete mode 100644 pythonapi/kernel.rst delete mode 100644 pythonapi/map.rst.inc delete mode 100644 pythonapi/object.rst delete mode 100644 pythonapi/object_controller.rst delete mode 100644 pythonapi/objects.rst delete mode 100644 pythonapi/player.rst delete mode 100644 pythonapi/services.rst delete mode 100644 pythonapi/tangible.rst delete mode 100644 pythonapi/utility.rst delete mode 100644 tools/cmake/FindSphinx.cmake delete mode 100644 tools/windows/user_project.vcxproj.in diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 9d842ed..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build/ -conf.py diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 2c1f5d9..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,93 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -project(swganh-docs CXX) - -# current version -if(NOT DEFINED swganh_VERSION) - set(swganh_VERSION_MAJOR 0) - set(swganh_VERSION_MINOR 4) - set(swganh_VERSION_PATCH 0) - set(swganh_VERSION - ${swganh_VERSION_MAJOR}.${swganh_VERSION_MINOR}.${swganh_VERSION_PATCH}) -endif() - -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/tools/cmake") - -find_package(Sphinx REQUIRED) - -if(NOT DEFINED SPHINX_THEME) - set(SPHINX_THEME default) -endif() - -if(NOT DEFINED SPHINX_THEME_DIR) - set(SPHINX_THEME_DIR) -endif() - -# configured documentation tools and intermediate build results -set(BINARY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/_build") - -# Sphinx cache with pickled ReST documents -set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees") - -# HTML output directory -set(SPHINX_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/html") - -if(NOT DEFINED SWGPY_DIR) - set(SWGPY_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) -endif() - -if(WIN32) - foreach(configuration ${CMAKE_CONFIGURATION_TYPES}) - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in" - "${BINARY_BUILD_DIR}/${configuration}/conf.py" - @ONLY) - endforeach() - - set(BINARY_BUILD_DIR "${BINARY_BUILD_DIR}/$") - set(SPHINX_CACHE_DIR "${SPHINX_CACHE_DIR}/$") - set(SPHINX_HTML_DIR "${SPHINX_HTML_DIR}/$") -else() - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in" - "${BINARY_BUILD_DIR}/conf.py" - @ONLY) -endif() - -file(GLOB_RECURSE DOCUMENTS *.rst *.in) - -# Group the source files based on the directory structure. -FOREACH(__source_file ${DOCUMENTS}) - STRING(REGEX REPLACE "(${CMAKE_CURRENT_SOURCE_DIR}/)((.*/)*)(.*)" "\\2" __source_dir "${__source_file}") - STRING(REGEX REPLACE "(${CMAKE_CURRENT_SOURCE_DIR}/${__source_dir})(.*)" "\\2" __source_filename "${__source_file}") - - STRING(REPLACE "/" "\\\\" __source_group "${__source_dir}") - SOURCE_GROUP("${__source_group}" FILES ${__source_file}) -ENDFOREACH() - -if(WIN32) - set(WORKING_DIR "${SWGPY_DIR}/$\(Configuration\)") - set(DEPENDENCIES swgpy) -else() - set(WORKING_DIR "${SWGPY_DIR}") - set(DEPENDENCIES) -endif() - -add_custom_target(swganh_doc_html ALL - ${SPHINX_EXECUTABLE} - -q -b html - -c "${BINARY_BUILD_DIR}" - -d "${SPHINX_CACHE_DIR}" - -n - "${CMAKE_CURRENT_SOURCE_DIR}" - "${SPHINX_HTML_DIR}" - COMMENT "Building HTML documentation with Sphinx" - DEPENDS ${DEPENDENCIES} - WORKING_DIRECTORY "${WORKING_DIR}" - VERBATIM - SOURCES ${DOCUMENTS} -) - -configure_file( - ${PROJECT_SOURCE_DIR}/tools/windows/user_project.vcxproj.in - ${CMAKE_CURRENT_BINARY_DIR}/swganh_doc_html.vcxproj.user @ONLY) \ No newline at end of file diff --git a/book/architecture.rst b/book/architecture.rst deleted file mode 100644 index 10e9514..0000000 --- a/book/architecture.rst +++ /dev/null @@ -1,11 +0,0 @@ -========================================= -Server Architecture and Design Philosophy -========================================= - -Main Application Parts - -* ANH Library: general game engine (static library) -* SWGANH Library: swg precu14 game library (static library plugin) -* 3rd Party Plugins: plugins that extend or modify the functionality of the SWGANH Library -* SWGANH Executable: the application that is executed, loads swganh library and plugins - diff --git a/book/events.rst b/book/events.rst deleted file mode 100644 index 2f72f9c..0000000 --- a/book/events.rst +++ /dev/null @@ -1,33 +0,0 @@ -Events -====== - -Massively multiplayer online games are by necessity big. Really, really big. Think for just a moment about all the different categories of features that make up a game (referred to in the MMOServer code as **Services**): crafting, combat, chat, trading, movement... and the list can easily go on for some time. There is so much functionality provided by these services that in mots MMORPGs they need to be run across multiple processes and/or physical machines. - -Alright, we've established that the scope of developing a MMORPG is rediculous, if you don't believe me just ask for helpful starting advice at `StackOverflow`_ or `GameDev.net`_ [1]_. Still with me? Good, insanity is a must to proceed. Now you might be thinking: how do we manage all of this complexity without it turning into a big bowl of code spaghetti? - -The key to managing the complexity of many interacting services is good communication. There are two ways in which services need to communicate with each other: to inform an unknown number of interested parties that something significant has occurred (via the **Event Dispatcher**) and to make requests directly to a specific type of service (via the **Service Locator**). This article focuses on the motivation behind the Event Dispatcher and common usage patterns to help you quickly get up to speed with one of the most vital components of the SWG:ANH MMOServer engine. - -Overview --------- - -The Event Dispatcher consists of three main components starting with the **dispatcher** that serves as the focal point for services to communicate their current state with one another. Service helper objects, known as **listeners**, **connect** to the dispatcher and wait for specific types of messages, or **events**, to be **delivered**. Other services **notify** the dispatcher that an event has occurred, which in turn notifies all the listeners that have expressed interest in that event type. - -Events ------- - -Events are a way for a service to package information about an observable behavior that is either being performed or about to be performed. They are like a standardized language that all services have agreed upon as an acceptible way to communicate with one another. - -The most basic event type is, unsurprisingly, called the basic_event. It consists of a **subject**, the object responsible for invoking the event, and the **event data**, a collection of information that gives context for the event. - -Event Dispatcher ----------------- - - -Listeners ---------- - - -.. [1] If you're a hobbiest programmer with a mind on building an MMORPG expect to be met with many a "don't do it" suggestions along the way. - -.. _`StackOverflow`: http://www.stackoverflow.com -.. _`GameDev.net`: http://www.gamedev.net \ No newline at end of file diff --git a/book/index.rst b/book/index.rst deleted file mode 100644 index a67100c..0000000 --- a/book/index.rst +++ /dev/null @@ -1,14 +0,0 @@ -SWGANH Reference -================ - -.. toctree:: - :hidden: - - installation - architecture - services - plugins - events - scripting - -.. include:: /book/map.rst.inc diff --git a/book/installation.rst b/book/installation.rst deleted file mode 100644 index 912f1a1..0000000 --- a/book/installation.rst +++ /dev/null @@ -1,17 +0,0 @@ -================================= -Installing and Configuring SWGANH -================================= - -* :doc:`/book/installation_windows` -* :doc:`/book/installation_linux` -* :doc:`/book/installation_docs` -* :doc:`/book/installation_client` - - -.. toctree:: - :hidden: - - installation_windows - installation_linux - installation_docs - installation_client diff --git a/book/installation_client.rst b/book/installation_client.rst deleted file mode 100644 index 8e20183..0000000 --- a/book/installation_client.rst +++ /dev/null @@ -1,3 +0,0 @@ -======================== -Game Client Installation -======================== diff --git a/book/installation_docs.rst b/book/installation_docs.rst deleted file mode 100644 index eb31624..0000000 --- a/book/installation_docs.rst +++ /dev/null @@ -1,70 +0,0 @@ -=========================== -Documentation Install Guide -=========================== - -This guide is a walkthrough on setting up the SWGANH documentation to build as part of an existing SWGANH environment. For more information on how to set up SWGANH please see the relevant documentation. - -Sphinx -~~~~~~ - -Sphinx is used to generate the SWGANH developer documentation. - - -Sphinx on Windows ------------------ - -To install it on windows you need to first download and install the distribute package. Git Bash is recommend over the windows command prompt to run the following as it already comes with the **curl** utility. - -:: - - curl -O http://python-distribute.org/distribute_setup.py - python distribute_setup.py - easy_install Sphinx - -.. NOTE:: - - It is important that Sphinx is installed with support for Python3. The key to this is ensuring you install Sphinx using an easy_install (via the distribute package) that was built against Python 3. - -.. WARNING:: - - If you get an error stating "Bad file number" it may indicate a confict with UAC. To get around this open a normal windows command prompt and enter the command. - - :: - - easy_install Sphinx - -You will also need to add the path to Sphinx to the system PATH. In a default Python 3.2 install this path is `C:/Python32/Scripts`. - -Sphinx on Linux ----------------- - -To install it on Ubuntu use the following command: - -:: - - sudo easy_install3 Sphinx - -.. NOTE:: - - It is important that Sphinx is installed with support for Python3. The key to this is ensuring you install Sphinx using an easy_install (via the distribute package) that was built against Python 3. - - -Checkout and Build the Documentation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Right click on the swganh project directory (e.g. `C:/workspace/swganh`) and choose "to open "Git Bash here". Next we'll use git to checkout the latest version of the documentation source. - -:: - - git clone https://github.com/anhstudios/swganh-docs.git docs - -Run the following commands to generate the project and build the source with the documentation. - -:: - - cd build - cmake .. - cmake --build . - -This will kick off a full build of the project. The final documentation output can be found at `C:/workspace/swganh/build/docs/html/Debug`. - diff --git a/book/installation_linux.rst b/book/installation_linux.rst deleted file mode 100644 index 9f11755..0000000 --- a/book/installation_linux.rst +++ /dev/null @@ -1,176 +0,0 @@ -=================== -Linux Install Guide -=================== - -This chapter cover's the setup of SWGANH from source in a linux environment. This particular guide cover's installation using Ubuntu and should apply directly to most debian based flavors. Other flavors of linux should at minimum support GCC 4.6 and Python3. - -.. note:: - - This guide is based on Ubuntu 11.10. If you are building on another distro you may be required to install some of the 3rd party libraries manually. - -Installing Build Dependencies ------------------------------ - -The first step in a linux build is to ensure the major dependencies for building the project are installed and available. - -- Git 1.7+ -- GCC 4.6+ -- CMake 2.8.5+ -- Python 3.2+ -- GLM Math Library 0.9.2+ -- Boost 1.49+ -- Boost-Log 1.1+ -- TBB (Thread Building Blocks) 3.0+ -- Turtle 1.2 -- Mysql Server 5.1+ -- Mysql Connector C++ (Custom ANH Fork) - -In most cases modern linux distros will provide easily installable packages for most of the dependencies. First lets install the all the dependencies except for Boost, Mysql Connector C++ and Sphinx: - -:: - - sudo apt-get install g++ python3-dev libmysqlclient-dev mysql-server libtbb-dev libglm-dev git git-gui gitk subversion cmake make curl unzip libbz2-dev - -.. NOTE:: - - You may have noticed a few extra dependencies at the end, these are tools that'll make it easier to download and unpack files later on. - -During the installation of the above you will be asked to enter a password for the root mysql user. Be sure to remember this password for later in the installation process. - -The remaining dependencies require a little extra work to install properly on any linux distro. - -First up is Boost which needs to be linked specifically against Python3 so requires manual compilation and installation. In addition we make use of Boost-Log, a logging library that has been officially accepted into Boost but is currently in an incubation period. The interface is stable however and meets our requirments for logging. - -Download the latest source packages for Boost and Boost-log (at the time of this writing that is 1.49 and 1.1, respectively). - -:: - - curl -L -O http://downloads.sourceforge.net/project/boost/boost/1.49.0/boost_1_49_0.tar.bz2 - - svn co https://boost-log.svn.sourceforge.net/svnroot/boost-log/trunk/boost-log/ - -Next unpack both source packages and copy the Boost-log files into the main Boost package. - -:: - - tar -xvjf boost_1_49_0.tar.bz2 - - cp -R boost-log/boost/log boost_1_49_0/boost/log - cp -R boost-log/libs/log boost_1_49_0/libs/log - -When configuring its important to specify the version of Python that Boost should compile against. To do that navigate to the boost_1_49_0 directory and run the following command. - -:: - - cd boost_1_49_0 - ./bootstrap.sh --with-python=python3.2 - -Now that the environment is ready you can build boost by simply running the b2 command. - -:: - - ./b2 - sudo ./b2 install - -.. note:: - - Due to a bug in the bootstrap.sh file the Python root is not detected. For builds using the Ubuntu package version of Python this is not a problem, however, if you have installed Python to a non-standard location then you may get compile errors. In that case open up the **project-config.jam** file and add the path to the Python root as in the example below. - - :: - - python : 3.2 : /usr ; - -Turtle is a mocking library that is used for testing interactions between objects. This is a header only library and easy to install. Just download and unpack the library headers to the appropriate system path. - -:: - - cd ~ - curl -L -O http://downloads.sourceforge.net/project/turtle/turtle/1.2.0/turtle-1.2.0.tar.bz2 - sudo tar -xvjf turtle-1.2.0.tar.bz2 -C /usr/local - -This leaves only Mysql Connector C++ left on our list. This project is the official C++ connector from Mysql, however, it doesn't appear to be in active development at this time. For this reason we have had to create our own fork to support a few features that are missing from the official source. First make sure you're not in the Boost directory from the previous step and run the following: - -:: - - git clone https://github.com/anhstudios/mysql-connector-cpp.git - cd mysql-connector-cpp - cmake . - make - sudo make install - -Building the SWGANH Source --------------------------- - -With the dependencies out of the way the hard part is over. It's now time to checkout the SWGANH source and kick off the first build. Make sure you're not still inside the Mysql Connector C++ directory from the previous section before running these commands. - -:: - - git clone https://github.com/anhstudios/swganh.git - mkdir swganh/build - cd swganh/build - cmake .. - make - -Setting up the Database ------------------------ - -A new database installation is needed before the server can be started for the first time. To install the server navigate to the `swganh/data/sql` folder and execute the following command: - -:: - - ./setup.sh -u MYSQL_USERNAME -p MYSQL_PASSWORD - -Replace MYSQL\_USERNAME and MYSQL\_PASSWORD with the authentication data of a mysql user with appropriate privileges. - -.. NOTE:: - - You can use the root user for simple local installations, however, it is advised that you create a dedicated mysql user for your SWGANH installation in production environments. - -.. NOTE:: - - You can set a custom host using the -h flag (e.g. -h 192.168.0.100). - - The mysql executable can also be customized via the -m flag (e.g. -m mysql5). - -Configuring and Running the Server ----------------------------------- - -You are now entering the home stretch, all that's left is to update the SWGANH configuration and kick off the server. - -Open the `swganh/build/bin/config/swganh.cfg` file and edit the following items. First you will need to update the **tre_config** setting with the path to the **live.cfg** file in your SWGANH Game Client directory. - -.. note:: - - Some older SWGANH clients have this file named as **swg2uu_live.cfg**. - -.. note:: - - The game client does not run on unix environments, in this case the easiest solution is to upload a client directory from an already existing windows installation. - -.. warning:: - - Be sure to specify the live.cfg file that is **inside** the SWGANH Game Client directory and **NOT** the one inside the official Star Wars Galaxies directory. - -Second, update the mysql database connection information with the address and user you used to setup the database in the previous section. - -Finally, set the address in the **service.connection** section to your public facing IP and then save and close the file. - -You can now kick off the server by running this command in the **swganh/build/bin** directory: - -:: - - ./swganh - -To start the server in a background process you can use a tool like screen. - -:: - - screen ./swganh - -Hitting **ctrl+a** then **ctrl+d** will disconnect from the screen session but will leave the server running in the background. You can rejoin the server to shut it down with the following command: - -:: - - screen -r - -No output is sent to the console, you can view output from the server by viewing the log at `build/swganh.log`. diff --git a/book/installation_windows.rst b/book/installation_windows.rst deleted file mode 100644 index d04cf32..0000000 --- a/book/installation_windows.rst +++ /dev/null @@ -1,165 +0,0 @@ -===================== -Windows Install Guide -===================== - -The most common platform for building and developing SWGANH has been Windows and this chapter covers the easiest way to get started. The SWGANH project is developed on modern technologies and as such has a few minimum version requirements to be mindful about. Most notable is the minimum supported windows version, Vista. - -Installing Build Dependencies ------------------------------ - -The following is a complete list of the 3rd party dependencies that will need to be installed before building the SWGANH source. - -- Microsoft Visual Studio 2012 -- CMake 2.8.7+ -- Git 1.7+ -- Python 3.2 -- Mysql 5.1+ -- SWGANH Dependencies Package -- SWGANH Game Client - -Visual Studio 2012 -~~~~~~~~~~~~~~~~~~~~~~~ - -When installing Visual Studio, make sure to download the Ultimate edition, you can use it for free for 90 days, by that time Microsoft has promised they will release an Express version of Visual Studio 2012. -if you have an MSDN license you should be able to pick up professional or the highest SKU you have access to. - - http://www.microsoft.com/visualstudio/11/en-us/downloads#vs - -CMake 2.8.7+ -~~~~~~~~~~~~ - - -CMake is used to generate the project files for SWGANH source builds. When installing be sure to select the option to add CMake to the PATH. - - http://www.cmake.org/cmake/resources/software.html - -Git 1.7+ -~~~~~~~~ - -Git is used to check out and keep your local source in sync with the latest SWGANH chanages. We recommend installing the GitExtensions package which, in addition to the normal git utilities, provides nice GUI. - -While the Git Extensions package be sure to select the "msysgit" option to install the base Git utilitites. It is also advised that you select the option to add Git GUI and Git Bash to the context menu (right click). This makes it easy to right click on a directory and open the git gui or git bash prompts. - - http://code.google.com/p/gitextensions/downloads/list - -Python 3.2+ -~~~~~~~~~~~ - -Python is used for scripting as well as for generating the SWGANH documentation. After downloading and installing the latest Python 3.2 x86 binaries you will need to add the path to python to the system **PATH**. In a default Python 3.2 install this path is `C:/Python32`. - - http://python.org/download/ - -.. note:: - - Be sure to install the x86 (32bit) binaries and *NOT* the x86-64 (64bit) binaries, it would be bad. - -Mysql 5.1+ -~~~~~~~~~~ - -Mysql is used for database storage in the ANH project. This guide only covers the simplest of installation instructions, other more in-depth topics on database management may be provided in another document in the future. - -To start, download and install the latest Mysql Installer. Select the default developer installation which will provide you with all the tools needed to run and manage the SWGANH database. When the installation is complete you will need to add the path to mysql to the system PATH. In a default mysql installation this is `C:/Program Files/MySQL/MySQL Server 5.5/bin`. - - http://www.mysql.com/downloads/installer/ - -Setting Up the SWGANH Environment ---------------------------------- - -Now it's time to get the SWGANH environment set up and ready to begin building the source. First create a directory to hold all of your SWGANH related files. In this example we will use `C:/workspace` as our base directory. - -SWGANH Dependencies Package -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The Windows environment gives us the opportunity to prebuild the libraries that you will need to build the SWGANH source. Download the latest Visual Studio 2012 dependencies from the official SWGANH downloads page and unpack the contents into the workspace directory you created in the previous step. Afterwards, the directory structure should be as follows: `C:/workspace/vendor` - - https://github.com/anhstudios/swganh/downloads - -SWGANH Game Client -~~~~~~~~~~~~~~~~~~ - -The SWGANH Game Client can be installed from the unofficial SWGANH client installer. - - https://github.com/downloads/anhstudios/swganh/anhclient_setup.exe - -.. note:: - - The installer at this time requires a valid Star Wars Galaxies game client installation. In the future there will be an official installer that forgoes this requirement. - -Checkout and Build the Source -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Finally we get to the good stuff! Right click on the swganh workspace directory (e.g. `C:/workspace`) and choose "to open "Git Bash here". Next we'll use git to checkout the latest version of the source. - -:: - - git clone https://github.com/anhstudios/swganh.git - -Run the following commands to generate the project and build the source. - -:: - - mkdir swganh/build - cd swganh/build - cmake -G "Visual Studio 11" .. - cmake --build . - -.. WARNING:: - If you get an error about cmake not being able to find your PYTHON_LIBRARY. re-run the cmake -G command above adding in the following: - cmake -G "Visual Studio 11" -DPYTHON_LIBRARY="LOCATION_TO_PYTHON_DIR/libs" .. - where "LOCATION_TO_PYTHON_DIR" is where your Python32 folder resides. This seems to occur if Python is installed in Program Files x86.. - -This will kick off a full build of the project. The final output can be found at `C:/workspace/swganh/build/bin/Debug`. - -.. note:: - - The Visual Studio solution can be found at `C:/workspace/swganh/build/swganh.sln`. Use this to modify and build changes to existing source files. - -.. note:: - - Since the project files are located outside the source directory adding new files from within visual studio requires changing the default save location. - - To add a new file, manually create it in the src directory and then run the following from within the build directory. - - :: - - cmake .. - -.. note:: - - Documentation can be found in the `C:/workspace/swganh/build/docs/html/Debug` directory. Just open the **index.html** file in your favorite browser. - -Setting up the Database -~~~~~~~~~~~~~~~~~~~~~~~ - -A new database installation is needed before the server can be started for the first time. To install the server navigate to the `C:/workspace/swganh/data/sql` folder and copy the **setup.cfg-example** file to **setup.cfg**. Edit this file with the appropriate login information for the Mysql server you intend to use. - -.. NOTE:: - - Be sure to copy and **NOT** rename the setup.cfg-example file, lest you accidently try to remove it from the source on your next commit. - -.. NOTE:: - - You can use the root user for simple local installations, however, it is advised that you create a dedicated mysql user for your SWGANH installation in production environments. - -Next double click the setup.bat script. This will open up the database installer. Choose option #1 for a complete installation by typing 1 and hitting enter. Once this process completes you can quit the installer. - -Configuring and Running the Server -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You are now entering the home stretch, all that's left is to update the SWGANH configuration and kick off the server. - -Open the `C:/workspace/swganh/build/bin/Debug/config/swganh.cfg` file and edit the following items. First you will need to update the **tre_config** setting with the path to the **live.cfg** file in your SWGANH Game Client directory. - -.. note:: - - Some older SWGANH clients have this file named as **swg2uu_live.cfg**. - -.. warning:: - - Be sure to specify the live.cfg file that is **inside** the SWGANH Game Client directory and **NOT** the one inside the official Star Wars Galaxies directory. - -Second, update the mysql database connection information with the address and user you used to setup the database in the previous section. - -Finally, set the address in the **service.connection** section to your public facing IP and then save and close the file. - -You can now kick off the server by running the **swganh.exe** at `C:/workspace/swganh/build/bin/Debug/swganh.exe`. diff --git a/book/map.rst.inc b/book/map.rst.inc deleted file mode 100644 index 6b1b21f..0000000 --- a/book/map.rst.inc +++ /dev/null @@ -1,6 +0,0 @@ -* :doc:`/book/installation` -* :doc:`/book/architecture` -* :doc:`/book/services` -* :doc:`/book/plugins` -* :doc:`/book/events` -* :doc:`/book/scripting` diff --git a/book/plugins.rst b/book/plugins.rst deleted file mode 100644 index 0b81e80..0000000 --- a/book/plugins.rst +++ /dev/null @@ -1,7 +0,0 @@ -======= -Plugins -======= - -In order to add a large amount of customizability and flexibility within the SWGANH server. The developers have decided to utilize the idea of loading in objects dynamically. This allows custom plugins to be created that tweaks functionality, utilizes a different data source, and more just with a simple tweak in the configuration file. - -The plugin system provides a way to register how to create and destroy objects and then it uses registrations to create new objects on the fly. This registration is then available to the server at runtime and allows a quick and easy method to get objects as needed. diff --git a/book/scripting.rst b/book/scripting.rst deleted file mode 100644 index 5c942b7..0000000 --- a/book/scripting.rst +++ /dev/null @@ -1,13 +0,0 @@ -========= -Scripting -========= - -General Overview -~~~~~~~~~~~~~~~~ - -The SWGANH project uses `Python 3.x `_ for in game scripting. The most obvious area where scripting is used is within the in-game commands. Almost everything in SWG is a command, and they can all be processed through scripting. SWGANH has chosen Python as the preferred scripting language because of it's robustness, ease of use, and overall performance. Another reason is because the great C++ integration with the `Boost.Python `_ library. This allows us to have very nice integration with Python from C++ and vice versa. - -Why did SWGANH decide to use Scripting? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -SWGANH uses scripting for ease of use and flexibility in game features. -What this means is that anyone who decides to use SWGANH can expect the ability to easily add, remove, and tweak gameplay with minimal changes to the core application of SWGANH. This is something that was needed as SWGANH is first and foremost a platform for communities to gather around and build the Star Wars Galaxies game they have always wanted. While the base of the game is centered around Patch 14.1 (Pre-CU) we believe this allows for the highest amount of flexibility and overall generally enjoyment. diff --git a/book/services.rst b/book/services.rst deleted file mode 100644 index 962fba3..0000000 --- a/book/services.rst +++ /dev/null @@ -1,7 +0,0 @@ -======== -Services -======== - -Services are systems that are available the entire lifetime of the application. They also generally handle interactions directly with the SWG Protocol and they expose an API for controlling or accessing data that covers a feature set that can be used by all other services. - -Services are generally broken up into game system categories, but they can also be more generic than that. For example there is a Login Service that handles all of the interaction between the Client Login Messages, the database and server itself. This service handles these messages and allow you to do what is necessary with the data. In most cases, this involves interacting with the database and sending a SWG Protocol Message reply back to the Client. Most services follow this basic pattern, but they are not restricted to it. diff --git a/conf.py.in b/conf.py.in deleted file mode 100644 index a5cdf24..0000000 --- a/conf.py.in +++ /dev/null @@ -1,216 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SWG:ANH documentation build configuration file, created by -# sphinx-quickstart on Thu Aug 18 19:24:10 2011. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('@SWGPY_DIR@/@configuration@')) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.inheritance_diagram', 'sphinx.ext.graphviz'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'SWGANH' -copyright = u'2012, ANH Studios' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '@swganh_VERSION@' -# The full version, including alpha/beta/rc tags. -release = '@swganh_VERSION@' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = '@SPHINX_THEME@' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = ['@SPHINX_THEME_DIR@'] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'SWGANHdoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'SWGANH.tex', u'SWG:ANH Documentation', - u'ANH Studios', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'swganh', u'SWGANH Documentation', - [u'ANH Studios'], 1) -] diff --git a/contributing/index.rst b/contributing/index.rst deleted file mode 100644 index 27e8fb9..0000000 --- a/contributing/index.rst +++ /dev/null @@ -1,14 +0,0 @@ -Contributing -============ - -.. toctree:: - :hidden: - - issues - pull_requests - tests - security - standards - license - -.. include:: /contributing/map.rst.inc diff --git a/contributing/issues.rst b/contributing/issues.rst deleted file mode 100644 index e8a2127..0000000 --- a/contributing/issues.rst +++ /dev/null @@ -1,32 +0,0 @@ -================== -Reporting an Issue -================== - -If you find a bug or have any problems with the SWGANH server please report it. This helps us to make the SWGANH server as enjoyable to play on as possible. - -.. note:: - - If you think you've found a security issue, please use the special - :doc:`procedure ` instead. - -Before you create a new issue: - -* Consult the `documentation`_ to ensure you're using the SWGANH engine properly. -* Ask for assistance on the `forum`_ or on the #swganh `IRC channel`_ if you're unsure whether or not the problem you're having is a bug. - -If you have a bug use the `Issues tool`_ found at the official `SWGANH repository`_: - -* Use the title field to clearly describe the issue; - -* Describe the steps needed to reproduce the bug with short code examples - (providing a unit test that illustrates the bug is best); - -* Give as much details as possible about your environment (OS, Compiler Version, SWGANH Version, enabled plugins, ...); - -* *(optional)* Attach a :doc:`pull request `. - -.. _documentation: http://swganh.com/docs/ -.. _forum: http://swganh.com/forums/ -.. _IRC channel: irc://irc.freenode.net -.. _Issues tool: https://github.com/anhstudios/swganh/issues -.. _SWGANH repository: https://github.com/anhstudios/swganh \ No newline at end of file diff --git a/contributing/license.rst b/contributing/license.rst deleted file mode 100644 index 92e42a3..0000000 --- a/contributing/license.rst +++ /dev/null @@ -1,16 +0,0 @@ -============== -SWGANH License -============== - -SWGANH is released under the MIT license. - -The License -~~~~~~~~~~~ - -Copyright (c) 2011-2012 ANH Studios - -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. \ No newline at end of file diff --git a/contributing/map.rst.inc b/contributing/map.rst.inc deleted file mode 100644 index c920fa7..0000000 --- a/contributing/map.rst.inc +++ /dev/null @@ -1,7 +0,0 @@ -* :doc:`/contributing/issues` -* :doc:`/contributing/pull_requests` -* :doc:`/contributing/tests` -* :doc:`/contributing/security` -* :doc:`/contributing/standards` -* :doc:`/contributing/license` - \ No newline at end of file diff --git a/contributing/pull_requests.rst b/contributing/pull_requests.rst deleted file mode 100644 index 1ec4998..0000000 --- a/contributing/pull_requests.rst +++ /dev/null @@ -1,152 +0,0 @@ -========================= -Submitting a Pull Request -========================= - -The SWGANH team accepts code contributions via the GitHub Pull Request system. This allows us a tight integration with our issue tracking functionality as the two are often heavily entwined. - -To submit a patch first you will need to get and build the SWGANH source code: - -* Create and sign into a `GitHub`_ account. -* Fork the `SWGANH repository`_ by clicking the "**Fork**" button. -* After the forking process has completed, clone your fork: - -.. code-block:: bash - - $ git clone git@github.com:USERNAME/swganh.git - -* Add the official SWGANH repository as a remote named upstream: - -.. code-block:: bash - - $ cd swganh - $ git remote add upstream https://github.com/anhstudios/swganh.git - -* Build the code using the :doc:`official install guide `. - -Working on a Pull Requests -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Every pull request you create for a bug fix or new feature needs its own topic branch. - -.. note:: - - Until we reach a 1.0 release, all pull requests should be directed to the **develop** branch. - -Create a topic branch with the following command: - - git checkout -b BRANCH_NAME develop - -.. tip:: - - Use descriptive names for your topic branches. Pull requests that fix a particular issue should be named issue/XXX where XXX is the issue number. Branches for new features should be named with a feature/ prefix (e.g., feature/guild_system). - -The above will switch your working directory to the newly created branch. You are now ready to begin working on your issue or feature. Keep the following points in mind while working on code. - -* Follow the :doc:`coding standards `. -* If possible, add unit tests to prove that the bug is fixed or that the feature works as specified. -* Commit often and use good commit messages. - -Submitting a Pull Request -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Before you submit a pull request make sure to pull in the latest changes from the main develop line. This is especially important for long running feature additions. - -.. code-block:: bash - - $ git checkout develop - $ git fetch upstream - $ git merge upstream/develop - $ git checkout BRANCH_NAME - $ git rebase develop - -While running a ``rebase`` you may encounter merge conflicts. Use the ``git status`` command to see the unmerged files. Resolve all of the conflicts and then continue on with the rebase: - -.. code-block:: bash - - $ git add ... # add resolved files - $ git rebase --continue - -Check that all :doc:`tests ` pass and then push your branch to your GitHub repository: - -.. code-block:: bash - - $ git push origin BRANCH_NAME - -You can now discuss your branch on the `SWGANH IRC`_ or the `forums`_. When you are ready you can make a pull request from your GitHub page using the **Pull Request** button. - -Your pull request may generate feedback that requires additional work to your topic branch before it can be merged into the main development line. When pushing the requested changes back up to your GitHub repository be sure to rebase and not merge; then force the push back to origin: - -.. code-block:: bash - - $ git rebase -f upstream/master - $ git push -f origin BRANCH_NAME - -.. warning:: - - Always specify the branch name explicitly when doing a push -f (or --force) to avoid causing issues with other branches. - -Sometimes you may be asked to "squash" your commits. This is common when there are a number of similar changes to many files. Squashing commits will turn many commits into a single commit. Squashing is accomplished via ``rebase``: - -.. code-block:: bash - - $ git rebase -i head~3 - -The number 3 here must equal the amount of commits in your branch. After running this command a text editor will pop up and display a list of commits: - -:: - - pick 1a31be6 first commit - pick 7fc64b4 second commit - pick 7d33018 third commit - -To squash all commits into the first one, remove the word "pick" before the second and last commits and replace it with the word "squash" or just "s". When you save git will start rebasing and once complete will ask you to enter a new commit message (by default this is set to a listing of messages from all the commits). When finished execute the push command. - -.. code-block:: bash - - $ git push -f origin BRANCH_NAME - - -Testing Pull Requests -~~~~~~~~~~~~~~~~~~~~~ - -Members of the testing team have a vital role to play in ensuring that all the code going into the official development line is up to par. This involves testing contributed bug fixes or even brand new features from the core development team or from coders in the community. - -In order to begin testing make sure you already have a SWGANH environment :doc:`installed `. Before each round of testing make sure that you have the latest changes from the official repository. - -.. code-block:: bash - - $ git checkout develop - $ git fetch upstream - $ git merge upstream/develop - -Next it's time to find a Pull Request to review, these are listed at https://github.com/anhstudios/swganh/pulls. After clicking on a pull request you can identify the user that made the request and the branch they want pulled from. - -.. image:: /images/contributing/pull_requests_image_1.png - :align: center - -In the case of the example above the user is **dead1ock** who wants someone to merge in the **feature/spatial_indexing** branch. - -The first time that you test a pull request from a contributor you will need to add them as a remote so that you can fetch their changes. Note that this only needs to be completed the first time you test a pull request from a new contributor. - -.. code-block: bash - - # following the example above the USERNAME would be replaced with dead1ock - $ git remote add USERNAME git://github.com/USERNAME/swganh.git - -With the contributor's remote added its now time to pull in their code and build it. - -.. code-block: bash - - $ git fetch USERNAME - $ git checkout PULL_REQUEST_BRANCH - $ cd build - $ cmake .. - $ cmake --build . - -Replace **PULL_REQUEST_BRANCH** with the name identified from the pull request, in the example above this would be the **feature/spatial_indexing** branch. - -.. _GitHub: http://github.com -.. _SWGANH repository: http://github.com/anhstudios/swganh -.. _SWGANH IRC: irc://irc.swganh.org -.. _forums: http://swganh.com/forums - diff --git a/contributing/security.rst b/contributing/security.rst deleted file mode 100644 index 8fa3550..0000000 --- a/contributing/security.rst +++ /dev/null @@ -1,19 +0,0 @@ -Reporting a Security Issue -========================== - -Found a security issue in SWGANH? Don't use the forums or the issue tracker. All security issues must be sent to **security [at] -swganh.com** instead. Emails sent to this address are forwarded to -the SWGANH core-team private mailing-list. - -For each report, we first try to confirm the vulnerability. When it is -confirmed, the core-team works on a solution following these steps: - -1. Send an acknowledgement to the reporter; -2. Work on a patch; -3. Write a post describing the vulnerability, the possible exploits, and how to patch/upgrade affected applications; -4. Apply the patch to all maintained versions of SWGANH; -5. Publish the post on the official SWGANH blog. - -.. note:: - - While we are working on a patch, please do not reveal the issue publicly. \ No newline at end of file diff --git a/contributing/standards.rst b/contributing/standards.rst deleted file mode 100644 index 8f114e4..0000000 --- a/contributing/standards.rst +++ /dev/null @@ -1,62 +0,0 @@ -Coding Standards -================ - -These are a list of things to keep in mind, check for and apply to code you're writing for the SWG:ANH application. Keeping to this will help make it easier for everyone who works on the codebase to identify what is going on in the code you've written. These are also points that all reviewers should be applying to incoming code before it hits the develop line. Sharing these changes back with the developer is vital to improving everyone's common working knowledge. - -.. note:: When going through code it's very, very tempting to start applying this to everything, including sections outside the area you are currently giving attention to or reviewing. Do not give into this temptation as it will lead off into unknown territory and also cause the diffs to be even more crazy than normal. All code will get it's time in the light, be patient and stay the course because it's slow and steady that wins this race. - -Follow the agreed upon style guide ----------------------------------- - -When writing source or accepting it in ensure that it fits with the agreed upon style guide, a variation of the `Google C++ Style Guide`_. The following are where the ANH guide deviates from above: - -* Exceptions are allowed -* C++0x libraries are allowed (and encouraged) -* Enums must be ALL_CAPS_WITH_UNDERSCORES -* Non accessor/mutator functions should be camel case starting with a lower case, non-numeric character -* Documenting comments in headers should follow the Doxygen format -* Indent by 4 spaces instead of 2 -* No indentation before public, protected, private - -Order includes appropriately ----------------------------- - -See the Google C++ Style Guide `section`_ on this topic for further information on the how and why behind this item. - -Prefer standard algorithms to hand-written loops ------------------------------------------------- - -Hand written loops are often more verbose and slower than solutions that use the standard library algorithms, particularly when given the addition of lambdas in the latest standard. Always keep a copy of the `latest standard`_ handy, particularly section 25 on the Algorithms library. - -When you come up against a hand crafted loop consider: - -* What does this loop currently do? - - It is important when reviewing a piece of code to truly understand what it is currently doing. When looking at a fresh piece of code this is the most objective question to ask and should be the first one asked. - -* What is it trying to achieve? - - With an understanding of what the code is actually doing take a step back and look at what the code is doing in the context of the surrounding code and ask: What problem was the original author trying to solve? Compare the answer to this with what the code is currently doing. If they do not match roll up those sleeves and get to cleaning! - -* Can the intention and execution be improved by using a standard algorithm? - - How hard was identifying the intention and behavior of the code? If it was difficult to infer what the code was doing from a simple reading chances are it needs to be refactored. Consult the standard's algorithm section to see if there are any solutions to help. - -Simplify overly verbose logic ------------------------------ - -Take the time to fully understand the purpose of any function/method you are currently looking at. Once you know why it exists take a closer look at how the problem was originally solved. Often times our legacy code was written on code binges where constant tweaks were made to get things working and then never reviewed before making it into the main source line. There are many places still where hundreds of lines of code can be shrunk to tens of lines (or less). - -Add missing API documentation ------------------------------ - -Before the start of this initiative there existed almost no API documentation. In order to change this and build up a useful base of documentation whenever entering into an existing function/method take the time to understand what it's purpose is and then add a Doxygen style doc above its declaration. - -Remove commented sections of code ---------------------------------- - -If code shouldn't be there, remove it. Don't comment on how silly it is and leave it there as a testimony to the ignorance of others... nobody really cares. Just remove the code and clean up our source. And don't worry about losing any information, our projects and all their history are always available thanks to Git, just browse a files history to see its previous states. - -.. _`Google C++ Style Guide`: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml -.. _`section`: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Names_and_Order_of_Includes#Names_and_Order_of_Includes -.. _`latest standard`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf \ No newline at end of file diff --git a/contributing/tests.rst b/contributing/tests.rst deleted file mode 100644 index 356ad78..0000000 --- a/contributing/tests.rst +++ /dev/null @@ -1,38 +0,0 @@ -============ -Code Testing -============ - -Before submitting a :doc:`pull request`, you need to run the SWGANH test suite to check that your changes have not broken any existing code. - -Running the Test Suite with Visual Studio -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To run the test suite in Visual Studio first open the project and then right click on the "RUN TESTS". - -Running the Test Suite from the Command Line -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To run the test suite from the command line first build the project. - -.. code-block:: bash - - $ cmake --build . - -Next run the test suite: - - $ ctest -C Debug - -Creating New Tests -~~~~~~~~~~~~~~~~~~ - -To create a new test first create a file to store the test in. All test files must be suffixed with ``_unittest.cc`` or ``_unittest.h``. Next create your test according to the `googletest`_ documentation. - -Finally, re-run the cmake command to generate the test project and then re-build and test the project: - -.. code-block:: bash - - $ cmake .. - $ cmake --build . - $ ctest -C Debug - -.. _googletest: http://code.google.com/p/googletest/wiki/Primer diff --git a/cookbook/index.rst b/cookbook/index.rst deleted file mode 100644 index 3d9dfec..0000000 --- a/cookbook/index.rst +++ /dev/null @@ -1,13 +0,0 @@ -Cookbook -======== - -.. toctree:: - :hidden: - - plugins/best_practices - - scripting/command_scripts - - security/custom_authentication - -.. include:: /cookbook/map.rst.inc diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc deleted file mode 100644 index c5e0b06..0000000 --- a/cookbook/map.rst.inc +++ /dev/null @@ -1,11 +0,0 @@ -* **Plugins** - - * :doc:`/cookbook/plugins/best_practices` - -* **Scripting** - - * :doc:`/cookbook/scripting/command_scripts` - -* **Security** - - * :doc:`/cookbook/security/custom_authentication` diff --git a/cookbook/plugins/best_practices.rst b/cookbook/plugins/best_practices.rst deleted file mode 100644 index 87f9c5c..0000000 --- a/cookbook/plugins/best_practices.rst +++ /dev/null @@ -1,48 +0,0 @@ -.. index:: - single: Plugins; Best Practices - -Plugin Structure and Best Practices -=================================== - -The SWG:ANH plugin system has been designed to be easy to use and simple to -adapt to most situations. While creating a new plugin is not difficult, -following a few best practices will make things easier for the future -maintainers of your plugin (including yourself!). - - -Directory Structure -------------------- - -.. code-block:: text - - XXX/... - my_plugin/ - CMakeLists.txt - LICENSE - main.cc - resources/ - config/ - my_plugin.cfg.dist - doc/ - index.rst - scripts/ - -The ``XXX`` directory(ies) reflects the namespace structure of the plugin. - -The following files are mandatory: - -* ``CMakeLists.txt``: Describes how to build the plugin; -* ``main.cc``: Entry-point for the plugin; -* ``LICENSE``: The full license for the plugin code; -* ``resources/config/my_plugin.cfg.dist``: The default configuration file for your plugin; -* ``resources/doc/index.rst``: The root file for the plugin documentation. - -Python scripts/modules used by your plugin should be placed under the -``resources/scripts`` directory to ensure they are installed in the proper -location after building. - -.. note:: - - These rules are in place to ensure that the build system and other 3rd party - tools can rely on this default structure to perform their work. - diff --git a/cookbook/scripting/command_scripts.rst b/cookbook/scripting/command_scripts.rst deleted file mode 100644 index 9fd4cbc..0000000 --- a/cookbook/scripting/command_scripts.rst +++ /dev/null @@ -1,372 +0,0 @@ -Creating a New Command Script -============================= - -This will take you step by step on how to create a simple command script for SWGANH. -This assumes that you have followed the server setup instructions and it is working as expected. - -For this yeaexample I will be doing a very simple command, but one that has interaction with another player. -`Add Friend `_ - -Step 1 - Startup -~~~~~~~~~~~~~~~~ - -Add the script reference to the command table in the galaxy database. -Open up your favorite mysql editor program, edit the 'command' table and look for the script_hook column. -Here we are going to be putting in the location of our python script that we have yet to create. -In this case we are going to put 'scripts/commands/add_friend.py' into the script hook for the addFriend row. - -Step 2 - Basic Script -~~~~~~~~~~~~~~~~~~~~~ - -Now that this is done we can create our script. Open up your favorite python editor (I just use notepad++) -We know based on our documentation located `Here ` _ -That we want to use the 'add_friend' function in the Player class. - -.. NOTE:: - - The way the SWG hierarchy works is that `Player `_ is a seperate object than `Creature `_ - This means that the normal actor will not work to add a friend, we will need to get the `Player `_ somehow. - This is done through another function `get_player `_, this will return the player object and then we can continue. - -our script now looks like this... - -.. code-block:: py3 - - import swgpy.object - - # Get the player object - player = actor.get_player() - target_player = creature_target.get_player() - # Make sure the player object and the target exists - if player and target_player: - # Check if the player target is already in our friends list - if not player.is_friend(target_player.id): - player.add_friend(target_player.id) - actor.ObjectController().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_added', swgpy.ProseType.TT, target.id), False, False) - elif: - actor.ObjectController().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_duplicate', swgpy.ProseType.TT, target.id), False, False) - elif: - actor.ObjectController().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_not_found', swgpy.ProseType.TT, target.id), False, False) - -A couple of things to note here - -Number one is that we are getting both the player and the target player objects, and if these don't exist we display a message. -To determine which messages to send out, I used the `SWG String Search `_ and searched for 'friend_added' -Secondly we are using the ObjectController to send the message to the actor to let them know the target was either added or not. -We used ProseType of TT, as that's what is shown in the `SWG String Search `_ and passed it the 'target id of the creature' -The two False at the end just tell SendSystemMessage that we want to show it not just in the chatbox (also in the middle of the screen) and to only send it to the current actor. - -Step 3 - First Example Finished? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Lets save our script as add_friend.py in the data/scripts/commands folder -Build our server again (this will copy over the scripts from data/commands to bin/Debug/commands (if on Windows) -Then, we should be able to run our server and the command should execute as expected. - -You are done with your first simple example! - -Step 4 - Troubleshooting -~~~~~~~~~~~~~~~~~~~~~~~~ - -Or are you? The great thing about Python is you are able to tweak the script at runtime and see the results immediately during the next script run. -My first run through for example I got a somewhat cryptic message in the server console output - -:: - - Python error: - SyntaxError: (`invalid syntax`, (``, 12, 6, `\telif:\n`)) - -Woah... what does this all mean? Python lets us know that it didn't like our script and something is definitely wrong here. -Lets break it up piece by piece. - -*SyntaxError* This means python couldn't execute a particular line because it didn't know how to interpret it. -*12, 6* This is saying the error is on line 12 and in position 6 -*`\telif:\n`* -Well that narrows it down pretty well for us, we know that line 12, we have a tab indentation and an elif: and a newline, which is what the \t and \n are respectively -This tells me that it is most likely a formatting error, or elif is not the correct syntax in this case. -In reality this is me just making a dumb mistake, I realize that I should be using else: instead of elif: as elif is used for -Once i replace the elif with else: -I get a different error, saying NoneType does not have method get_player -The problem here is that our creature_target doesn't exist. I need to re-look at how add_friend is supposed to work... -It looks like it just simply uses a name as a parameter. - -Step 5 - Down the Rabbit Hole -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Since this is the first social kind of command added to the game we are going to have to do more work than expected. -We will need to create a new service that is going to allow us to interact with the database, and interact with the player itself. - -Lets start creating our new service. Go into swganh/src/ and I will create a new folder called 'social' -I need to create some files in here. I know I want to have a 'service' so I will create social_service.h and social_service.cc -I will also create a social_service_binding.h and social_service_binding.cc and a CMakeLists.txt -This should be all I need initially to get this service going. - -For CMakeLists.txt I copied it from an existing service and changed the name to 'social' That's really all I need to do for that. -We also need to open up CMakeLists.txt in src/swganh and put in the following: -add_subdirectory(social) - -This will allow our build system to recognize there is another CMakeLists.txt in the social folder and the parse it out accordingly. - -Step 6 - Services In Depth -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -We need to take a step back here and really go over what a service is in the context of swganh and why we should be creating one. -Services are generally available the entire lifetime of the server. They can handle SWG Protocols and expose APIs for controlling/accessing data -that covers a feature set that is orthogonal to all other services. -This means that the service is available as long as the Server is operational, it exposes some functionality to other services and/or scripts. - -Perect, this sounds like what we want. We want a service that is able to pull data from the database, have that data available the entire life of the server, -and we want to allow other services access to this data. - -Step 7 - Service Integration and Playing with Data -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -We have our existing social_service files and social_service_binding files, these are probably empty, so let's get these filled in. -Lets start with social_service.h - -As a header file, this describes what we are going to be doing with our service. Based on our services we can see that this service -is going to inherit from swganh::base::BaseService. Our code looks little like this *snippet* - -.. code-block:: c - - class SocialService : public swganh::base::BaseService - { - public: - explicit SocialService(swganh::app::KernelInterface* kernel); - - swganh::service::ServiceDescription GetServiceDescription(); - }; - -This sets up a very very basic structure, all we are doing here is just getting the service created, we will flesh it out later. -Lets just do the same for the .cc file - -.. code-block:: c - - SocialService::SocialService(KernelInterface* kernel) - : BaseService(kernel) - {} - - ServiceDescription SocialService::GetServiceDescription() - { - ServiceDescription service_description( - "SocialService", - "social", - "0.1", - "127.0.0.1", - 0, - 0, - 0); - - return service_description; - } - -Ok, basic structure is in place. -Let's get enough just to set up our friends list. -We know we will need to have a function that is called AddFriend takes in a Player object and a string as parameters and returns a true or false, if the player was found or not. -so lets do that... - -.. code-block:: c - - bool SocialService::AddFriend(const shared_ptr& player, const string& friend_name) - { - return true; - } - -Right now our function does nothing and just returns true. -What we want to do is build out a simple interface as we know that this social service will end up doing a lot more than just adding a friend. -We know that we need to interact with the database and get some data, we can and should do this using a plugin. More about plugins and how they interact `HERE <>_` - -Step 8 - Setting up the Database Provider and Interface -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The provider interface is a pretty common pattern in our codebase, so lets do what we usually do and take a look at an example. in swganh/character/character_provider_interface.h -we can see a very similar thing to what we will need to do. In fact actually it looks like what we really want to do is just add to the character_provider_interface a function -that will perform the required action. What we really want is a way to look up a character name to see if they exist, this sounds just like something the character provider should do for us. - -Lets open the character_provider_interface.h and add a few lines. - -.. code-block:: c - - virtual uint64_t GetCharacterIdByName(const std::string& name) = 0; - -Ok, now we need to update the existing mysql_character plugin to take into consideration this change. - -our mysql_character_provider.h has added this. - -.. code-block:: c - - virtual uint64_t GetCharacterIdByName(const std::string& name); - -and our mysql_character_provider.cc has filled in the details for this function. - -.. code-block:: c - - uint64_t MysqlCharacterProvider::GetCharacterIdByName(const string& name) - { - uint64_t character_id = 0; - try { - auto conn = kernel_->GetDatabaseManager()->getConnection("swganh_galaxy"); - auto statement = std::unique_ptr( - conn->prepareStatement("SELECT id FROM object where custom_name like ? and type_id = ?;") - ); - statement->setString(1, name + '%'); - statement->setUInt(2, swganh::object::Player::type); - auto result_set = std::unique_ptr(statement->executeQuery()); - while(result_set->next()) - { - character_id = result_set->getUInt64(1); - } - - } catch(sql::SQLException &e) { - LOG(error) << "SQLException at " << __FILE__ << " (" << __LINE__ << ": " << __FUNCTION__ << ")"; - LOG(error) << "MySQL Error: (" << e.getErrorCode() << ": " << e.getSQLState() << ") " << e.what(); - } - return character_id; - } - -Now lets set up the interaction with the character provider plugin and see what this looks like. - -.. code-block:: c - - bool SocialService::AddFriend(const shared_ptr& player, const string& friend_name) - { - uint64_t friend_id = character_provider_->GetCharacterIdByName(friend_name); - /// If we found our friend, lets add them to our friends list (which will get updated by the player) - if (friend_id > 0) - { - player->AddFriend(friend_name); - // This persists the player object immediately. - kernel()->GetServiceManager()->GetService - ("SimulationService")->PersistObject(player->GetObjectId()); - - return true; - } - - return false; - } - -That is quite easy to follow and very modular, we can change what we are using to actually get the Character Id without having to rework this code. -This is a huge advantage of interfaces and why you see them in our codebase so frequently. Please check out the full social_service.h and .cc for more details. - -Step 9 - Registering the Service -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Now that we have a service created and compiling, we can add it to our server startup process. -Lets open up swganh_app.cc this is quite a large file and really does a lot of the work of starting up the game server. -first we need to 'include' our file that we created, so the swganh app knows about it. -#include "swganh/social/social_service.h" - -Next lets go down to where all the other services are loaded: LoadCoreServices. - -Lets add this in under the last service there: - -.. code-block:: c - - kernel_->GetServiceManager()->AddService( - "SocialService", - make_shared(kernel_.get())); - -Now we'll build the server, all should be good. - -Step 10 - Setting up bindings -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Now that we've created a very simple service with a very simple API, we want to expose this to Python to use in our script. -We do this through a process called binding. Fortunately most of the hard work is done for us with Boost.Python -All we need to do is tell Boost.Python about our service and it will automatically create a module for us. -Lets see what that looks like now. This is social_service_binding.h - -.. code-block:: c - - #include "swganh/python_shared_ptr.h" - #include "social_service.h" - - #include - - using namespace swganh::social; - using namespace boost::python; - using namespace std; - - void exportSocialService() - { - class_, boost::noncopyable>("SocialService", "The social service handles services that involve social actions", no_init) - .def("add_friend", &SocialService::AddFriend, "Checks the database to see if the character name exists and then adds the friend to the player") - ; - } - -As you can see this is a very simple example, we are using Boost.Python to basically create a python module which describes this C++ class and methods. -Most services are going to be very similar to this, so this is a good template to go off. -As you can see we have added in our 'AddFriend' method, this is to be expose to python as "add_friend" - -There is just one more step in order for this binding to work properly... -We need to now add a way to get to this service. This is done in the ANH Core through a system called the Service Manager. -Luckily we have an example to pull from on how to expose a service through this. -We will be opening up swganh_kernel_binding.h in app_binding. - -This will be used to expose all services out to Python. We will be using the SimulationService as an example to copy from. - -.. code-block:: py3 - - class_("ServiceManager", "provides an interface to common services", no_init) - .def("simulation_service", make_function( - bind(&swganh::service::ServiceManager::GetService, std::placeholders::_1, "SimulationService"), - default_call_policies(), - boost::mpl::vector, swganh::service::ServiceManager*>()), - "returns an internal refrence of the :class:`.SimulationService`") - -This is actually pretty complicated code and there is a lot of magic going on behind the scenes, but all we need to know is that we are exposing the -service to python as a shared_ptr. We can literally replace simulation with social and this will work as expected. - -Step 11 - Back to the script! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Ok, so now we know that we need to use the social service that we set up to add a friend. We also know through our documentation that we can -get to services through the :class:`.SWGKernel` service_manager -So lets add that call in the script after we check to see if the name is already in our friends list. -Next we need to send the player a message if the command succeeded or not. From the documentation again, we see that in order to send messages to the client -we need to get the Controller of the object and send a message. -The syntax is this - -.. code-block:: py3 - - actor.Controller().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_added', swgpy.ProseType.TT, friend_request_name), False, False) - -This is telling the code to get the controller object, invoke the SendSystemMessage using it's OutOfBand constructor that we are building right into the command. -We are telling it that it's a TT ProseType type, which we can see by looking `SWG Strings cmnty `_ -This fits right in with what the Strings message says we want to do. -Building out our script a little more it now looks like this - -.. code-block:: py3 - - import re, swgpy.object - - split = re.split('\W+', command_string) - friend_request_name = split[0] - print(friend_request_name) - # Get the player object - player = actor.get_player() - if player: - # Check if the name is already in our friends list - if not player.is_friend(friend_request_name): - added = kernel.service_manager().social_service().add_friend(player, friend_request_name) - if added: - print(added) - actor.Controller().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_added', swgpy.ProseType.TT, friend_request_name), False, False) - else: - print(added) - actor.Controller().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_not_found', swgpy.ProseType.TT, friend_request_name), False, False) - else: - print(added) - actor.Controller().SendSystemMessage(swgpy.OutOfBand('cmnty', 'friend_duplicate', swgpy.ProseType.TT, friend_request_name), False, False) - else: - print('Player object not found for object id' + actor.id) - -And we run it in our server and now we get a response, saying that our friend was added (if he exists on the server)! - -There are more things to keep in mind such as checking the ignore list, checking to see if the added friend is online and sending a message update. -This example will not cover those scenarios but you can check them out in the existing add_friend.py script. - -This example was more of a step by step process that followed MY particular though pattern. There can be other ways of doing things, I just -hope this was helpful. For any particular or in-depth questsions, please hit us up on IRC@ irc.swganh.com #swganh - -~Kyle Craviotto \ No newline at end of file diff --git a/cookbook/security/custom_authentication.rst b/cookbook/security/custom_authentication.rst deleted file mode 100644 index 21eda77..0000000 --- a/cookbook/security/custom_authentication.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. index:: - single: Login; Custom Authentication - -How to customize account authentication -======================================= - -The SWG emulator scene has had a number of various communities spring up around -over the years, many of which plan on running their own Galaxy once there is a -project far enough along to sustain an economy. Chances are, if you're managing -one of these communities, you already have a forum or some other community -portal application with account credentials for each of your players. This -Cookbook entry shows you how to create a plugin that uses the account -credentials from a phpBB3 forum for the Login server authentication. - diff --git a/images/contributing/pull_requests_image_1.png b/images/contributing/pull_requests_image_1.png deleted file mode 100644 index 98c4511cae73e95f96d2e8b16d2c507baf94ca42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27759 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 - - - $(SolutionDir)html\$(Configuration)\index.html - WebBrowserDebugger - - - WebBrowserDebugger - $(SolutionDir)html\$(Configuration)\index.html - - \ No newline at end of file From 373e83df57b86e66a480c66959b6cfe46240d1ea Mon Sep 17 00:00:00 2001 From: Indota Date: Wed, 25 Sep 2013 18:04:06 -0400 Subject: [PATCH 5/9] Git Setup Guide Adding Git Setup Guide to the new Contribution folder. This is a test, and may need to be altered a bit. --- contributing/Git Setup.rst | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 contributing/Git Setup.rst diff --git a/contributing/Git Setup.rst b/contributing/Git Setup.rst new file mode 100644 index 0000000..05b2b0a --- /dev/null +++ b/contributing/Git Setup.rst @@ -0,0 +1,50 @@ +Installing and Setting Up Git +============ + +At the heart of GitHub is an open source version control system (VCS) called Git*. Created by the same team that created Linux, Git is responsible for everything GitHub related that happens locally on your computer. + +Download and install the latest version of Git. + +Use the default options for each step. + +Setup Git +---------- + +Now that you have Git installed, it's time to configure your settings. To do this you need to open Git Bash (not the Windows command line). + +Need a quick lesson about Git Bash? + +Git Configuration +---------- + +**User name** + +First you need to tell git your name, so that it can properly label the commits you make. + +:: + git config --global user.name "Your Hame Here" + # Sets the default name for git to use when you commit + +**Email** + +Git saves your email address into the commits you make. We use the email address to associate your commits with your GitHub account. + +:: + git config --global user.email "your_email@example.com" + # Sets the default email for git to use when you commit + +Your email address for Git should be the same one associated with your GitHub account. If it is not, see this guide for help adding additional emails to your GitHub account. If you want to keep your email address hidden, this guide may be useful to you. + + +Password caching +---------- + +The last option we need to set will tell git that you don't want to type your username and password every time you talk to a remote server. + +Tip: You need git 1.7.10 or newer to use the credential helper To use this option, you need install a credential helper. + +GitHub for Windows includes this helper, and provides a git shell so you don't need to install and configure git manually. + +If you don't want to use GitHub for Windows, you can download the helper for your OS here: + +Windows Vista, 7, & 8 (.NET 4.0 required) Source Unzip the file and run the git-credential-winstore.exe program inside. This will start up the helper and update your git config to use it. \ No newline at end of file From dbc41006ef480bacd761b551c9702f63909391b5 Mon Sep 17 00:00:00 2001 From: Indota Date: Wed, 25 Sep 2013 18:21:16 -0400 Subject: [PATCH 6/9] Fixed Git Setup Guide --- contributing/Git Setup.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/contributing/Git Setup.rst b/contributing/Git Setup.rst index 05b2b0a..7e7eeb6 100644 --- a/contributing/Git Setup.rst +++ b/contributing/Git Setup.rst @@ -5,6 +5,9 @@ At the heart of GitHub is an open source version control system (VCS) called Git Download and install the latest version of Git. +`Download and install the latest version of Git. +`_. + Use the default options for each step. Setup Git @@ -12,16 +15,15 @@ Setup Git Now that you have Git installed, it's time to configure your settings. To do this you need to open Git Bash (not the Windows command line). -Need a quick lesson about Git Bash? - Git Configuration ---------- -**User name** +**Username** First you need to tell git your name, so that it can properly label the commits you make. -:: +.. code-block:: bash + git config --global user.name "Your Hame Here" # Sets the default name for git to use when you commit @@ -29,7 +31,8 @@ First you need to tell git your name, so that it can properly label the commits Git saves your email address into the commits you make. We use the email address to associate your commits with your GitHub account. -:: +.. code-block:: bash + git config --global user.email "your_email@example.com" # Sets the default email for git to use when you commit From eebb3d1728e180ea1927c3cd38cdea0ba423ad18 Mon Sep 17 00:00:00 2001 From: Indota Date: Wed, 25 Sep 2013 18:22:19 -0400 Subject: [PATCH 7/9] Final Fix for Git Setup Guide --- contributing/Git Setup.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/contributing/Git Setup.rst b/contributing/Git Setup.rst index 7e7eeb6..173ebdb 100644 --- a/contributing/Git Setup.rst +++ b/contributing/Git Setup.rst @@ -3,8 +3,6 @@ Installing and Setting Up Git At the heart of GitHub is an open source version control system (VCS) called Git*. Created by the same team that created Linux, Git is responsible for everything GitHub related that happens locally on your computer. -Download and install the latest version of Git. - `Download and install the latest version of Git. `_. From fea1f8f84520e5af08b86de9045656fa21d7ff13 Mon Sep 17 00:00:00 2001 From: Indota Date: Wed, 25 Sep 2013 18:35:02 -0400 Subject: [PATCH 8/9] Adding Using Git Guide --- contributing/Using Git.rst | 70 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 contributing/Using Git.rst diff --git a/contributing/Using Git.rst b/contributing/Using Git.rst new file mode 100644 index 0000000..b5d4218 --- /dev/null +++ b/contributing/Using Git.rst @@ -0,0 +1,70 @@ +Using Git to Contribute +============ + +If you have not already, you need to install and set up Git before you can perform these steps. If you need help with doing that see the Git Setup guide in the contributing folder. + +The process you are about to preform is to fork a repository. Which makes a copy of it for your Github account. While SWGANH is open source, we do not allow direct commits. This is so developers can review the accuracy of the code. Accuracy can be a multitude of things, including: It's functionality, It's ability to perform, If it has bugs, or even if it is content is before publish 14.1. + +Forking a Repository +---------- + +To start, you need to fork the repository you want to work with. In this instance we will say it is "swganh", the main server core. Forking adds a copy of the repository to your account. It is the first step in contributing. + +.. image:: https://github-images.s3.amazonaws.com/help/Bootcamp-Fork.png + +Cloning your Repository +---------- + +The next step is to clone your repository with Git. This is downloading it to your computer. To do so, run the following code. + +.. code-block:: bash + + cd C:/Users/your-user-account/where-ever-you-want-your-repository + # Goes to that specified location. That is where your files will get downloaded too. + git clone https://github.com/**your-username**/swganh.git + # Clones your fork of the repository into the current directory in terminal + + +Committing +---------- + +After you have changed a file in the source or added some content and you wish to submit it to be reviewed by the Developers, you can make a commit. + +.. code-block:: bash + + git status + # lists the status of the master. Telling you what files are different from the current public + # repository on github (if you used "cd C:/your-origin-whatever") + +Find the files you want to change and type + +.. code-block:: bash + + git add path-to-file.file-type + # Adds the specified files. + +If you alter multiple files and want to commit all of them, you can use: + +.. code-block:: bash + + git add * + +If you delete a file and want it to be completley removed/deleted from the repository when you commit, you can use: + +.. code-block:: bash + + git rm * (or git rm path-to-file.file-type + +Then when you are ready to commit: + +.. code-block:: bash + git commit "Added Rebel Themepark" + # Where the "" represents the commit message. + + +Submitting a Pull Request +---------- + +When you have a commit, or more than one commit ready to be sent for review you need to submit a "Pull Request" so developers can preview your changes, then approve or decline it. Do that on this page: + +https://github.com/anhstudios/swganh/compare \ No newline at end of file From 53d6f9bd7231448cb7f75f58d89c69f60d177cba Mon Sep 17 00:00:00 2001 From: Indota Date: Sat, 28 Sep 2013 19:20:23 -0400 Subject: [PATCH 9/9] Renamed Contribute Folder "contributing" now renamed to "How to Contribute" for a better understanding of what this folder has inside it. --- {contributing => How to Contribute}/Git Setup.rst | 0 {contributing => How to Contribute}/Using Git.rst | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {contributing => How to Contribute}/Git Setup.rst (100%) rename {contributing => How to Contribute}/Using Git.rst (100%) diff --git a/contributing/Git Setup.rst b/How to Contribute/Git Setup.rst similarity index 100% rename from contributing/Git Setup.rst rename to How to Contribute/Git Setup.rst diff --git a/contributing/Using Git.rst b/How to Contribute/Using Git.rst similarity index 100% rename from contributing/Using Git.rst rename to How to Contribute/Using Git.rst