Permalink
Browse files

Bullet physics and transmit new datestamp on login

  • Loading branch information...
1 parent 8b4dca5 commit 0e28274fdf3b9ed51715ac9bd73021b9992dffd0 croxis committed May 20, 2012
View
930 ITF.sublime-workspace
@@ -3,27 +3,151 @@
{
"selected_items":
[
+ [
+ "sol",
+ "SolarSystemSystem (class)"
+ ],
+ [
+ "ge",
+ "getSystem (function)"
+ ],
+ [
+ "Physics",
+ "PhysicsSystem (global, class)"
+ ],
+ [
+ "comp",
+ "component (local, instance)"
+ ],
+ [
+ "act",
+ "activeConnections"
+ ],
+ [
+ "l",
+ "lastAck (attribute, instance)"
+ ],
+ [
+ "getC",
+ "getConnection"
+ ],
+ [
+ "my",
+ "myPyDatagram (local, instance)"
+ ],
+ [
+ "send",
+ "sendLogin (attribute, function)"
+ ],
+ [
+ "L",
+ "LOGIN_ACCEPT (variable)"
+ ],
+ [
+ "packe",
+ "packetCount (attribute, instance)"
+ ],
+ [
+ "user",
+ "userName (local, instance)"
+ ],
+ [
+ "add",
+ "addComponent"
+ ],
+ [
+ "Acc",
+ "AccountComponent (global, class)"
+ ],
+ [
+ "cre",
+ "createEntity"
+ ],
+ [
+ "Solar",
+ "SolarSystemSystem"
+ ],
+ [
+ "solar",
+ "solarSystemRoot (local, instance)"
+ ],
+ [
+ "sola",
+ "solarDB (global, instance)"
+ ]
]
},
"buffers":
[
{
+ "file": "serverNet.py",
+ "settings":
+ {
+ "buffer_size": 5908,
+ "line_ending": "Unix"
+ }
+ },
+ {
+ "file": "protocol.py",
+ "settings":
+ {
+ "buffer_size": 842,
+ "line_ending": "Unix"
+ }
+ },
+ {
"file": "main.py",
"settings":
{
- "buffer_size": 0,
+ "buffer_size": 5103,
+ "line_ending": "Unix"
+ }
+ },
+ {
+ "file": "universals.py",
+ "settings":
+ {
+ "buffer_size": 484,
+ "line_ending": "Unix"
+ }
+ },
+ {
+ "file": "solarSystem.py",
+ "settings":
+ {
+ "buffer_size": 4416,
+ "line_ending": "Unix"
+ }
+ },
+ {
+ "file": "ships.py",
+ "settings":
+ {
+ "buffer_size": 457,
+ "line_ending": "Unix"
+ }
+ },
+ {
+ "file": "client.py",
+ "settings":
+ {
+ "buffer_size": 3555,
"line_ending": "Unix"
}
}
],
- "build_system": "Packages/Python/Python.sublime-build",
+ "build_system": "Packages/User/ITF Server Client.sublime-build",
"command_palette":
{
- "height": 0.0,
+ "height": 285.0,
"selected_items":
[
+ [
+ "Package Control: ",
+ "Package Control: Remove Package"
+ ]
],
- "width": 0.0
+ "width": 602.0
},
"console":
{
@@ -40,7 +164,19 @@
},
"file_history":
[
- "/home/croxis/.config/sublime-text-2/Packages/Default/Preferences.sublime-settings"
+ "/home/croxis/.config/sublime-text-2/Packages/User/ITF Server Client.sublime-build",
+ "/home/croxis/src/ITF/globals.py",
+ "/home/croxis/.config/sublime-text-2/Packages/Pylinter/Pylinter.sublime-settings",
+ "/home/croxis/.config/sublime-text-2/Packages/User/Pylinter.sublime-settings",
+ "/home/croxis/src/ITF/ITF.sublime-project",
+ "/home/croxis/src/SandBox/__init__.py",
+ "/home/croxis/src/ITF/solarsystem.yaml",
+ "/home/croxis/.config/sublime-text-2/Packages/SublimeCodeIntel/Base File.sublime-settings",
+ "/home/croxis/.config/sublime-text-2/Packages/Default/Preferences.sublime-settings",
+ "/home/croxis/.config/sublime-text-2/Packages/User/Python.sublime-settings",
+ "/home/croxis/.config/sublime-text-2/Packages/User/SideBarGit.sublime-settings",
+ "/home/croxis/.config/sublime-text-2/Packages/SideBarGit/SideBarGit.sublime-settings",
+ "/home/croxis/.config/sublime-text-2/Packages/User/Preferences.sublime-settings"
],
"find":
{
@@ -51,20 +187,24 @@
"height": 0.0,
"where_history":
[
+ "*.py"
]
},
"find_state":
{
- "case_sensitive": false,
+ "case_sensitive": true,
"find_history":
[
+ "SandBox",
+ "NodePath"
],
"highlight": true,
"in_selection": false,
"preserve_case": false,
"regex": false,
"replace_history":
[
+ "sandbox"
],
"reverse": false,
"show_context": true,
@@ -75,15 +215,344 @@
"groups":
[
{
- "selected": 0,
+ "selected": 4,
"sheets":
[
{
"buffer": 0,
+ "file": "serverNet.py",
+ "settings":
+ {
+ "buffer_size": 5908,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 2523,
+ 2523
+ ]
+ ],
+ "settings":
+ {
+ "annotations":
+ [
+ "TODO",
+ "README",
+ "FIXME"
+ ],
+ "csslint_options":
+ {
+ "adjoining-classes": "warning",
+ "box-model": true,
+ "box-sizing": "warning",
+ "compatible-vendor-prefixes": "warning",
+ "display-property-grouping": true,
+ "duplicate-background-images": "warning",
+ "duplicate-properties": true,
+ "empty-rules": true,
+ "errors": true,
+ "fallback-colors": "warning",
+ "floats": "warning",
+ "font-faces": "warning",
+ "font-sizes": "warning",
+ "gradients": "warning",
+ "ids": "warning",
+ "import": "warning",
+ "important": "warning",
+ "known-properties": true,
+ "outline-none": "warning",
+ "overqualified-elements": "warning",
+ "qualified-headings": "warning",
+ "regex-selectors": "warning",
+ "rules-count": "warning",
+ "shorthand": "warning",
+ "text-indent": "warning",
+ "unique-headings": "warning",
+ "universal-selector": "warning",
+ "vendor-prefix": true,
+ "zero-units": "warning"
+ },
+ "gjslint_ignore":
+ [
+ 110
+ ],
+ "gjslint_options":
+ [
+ ],
+ "javascript_linter": "jshint",
+ "jshint_options":
+ {
+ "browser": true,
+ "evil": true,
+ "regexdash": true,
+ "sub": true,
+ "trailing": true,
+ "wsh": true
+ },
+ "pep8_ignore":
+ [
+ "E501"
+ ],
+ "perl_linter": "perlcritic",
+ "pyflakes_ignore":
+ [
+ ],
+ "pyflakes_ignore_import_*": true,
+ "sublimelinter": true,
+ "sublimelinter_delay": 0,
+ "sublimelinter_disable":
+ [
+ ],
+ "sublimelinter_executable_map":
+ {
+ },
+ "sublimelinter_fill_outlines": false,
+ "sublimelinter_gutter_marks": false,
+ "sublimelinter_notes": false,
+ "sublimelinter_objj_check_ascii": false,
+ "sublimelinter_popup_errors_on_save": false,
+ "sublimelinter_syntax_map":
+ {
+ "Python Django": "python"
+ },
+ "sublimelinter_wrap_find": true,
+ "syntax": "Packages/Python/Python.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "type": "text"
+ },
+ {
+ "buffer": 1,
+ "file": "protocol.py",
+ "settings":
+ {
+ "buffer_size": 842,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 824,
+ 824
+ ]
+ ],
+ "settings":
+ {
+ "annotations":
+ [
+ "TODO",
+ "README",
+ "FIXME"
+ ],
+ "csslint_options":
+ {
+ "adjoining-classes": "warning",
+ "box-model": true,
+ "box-sizing": "warning",
+ "compatible-vendor-prefixes": "warning",
+ "display-property-grouping": true,
+ "duplicate-background-images": "warning",
+ "duplicate-properties": true,
+ "empty-rules": true,
+ "errors": true,
+ "fallback-colors": "warning",
+ "floats": "warning",
+ "font-faces": "warning",
+ "font-sizes": "warning",
+ "gradients": "warning",
+ "ids": "warning",
+ "import": "warning",
+ "important": "warning",
+ "known-properties": true,
+ "outline-none": "warning",
+ "overqualified-elements": "warning",
+ "qualified-headings": "warning",
+ "regex-selectors": "warning",
+ "rules-count": "warning",
+ "shorthand": "warning",
+ "text-indent": "warning",
+ "unique-headings": "warning",
+ "universal-selector": "warning",
+ "vendor-prefix": true,
+ "zero-units": "warning"
+ },
+ "gjslint_ignore":
+ [
+ 110
+ ],
+ "gjslint_options":
+ [
+ ],
+ "javascript_linter": "jshint",
+ "jshint_options":
+ {
+ "browser": true,
+ "evil": true,
+ "regexdash": true,
+ "sub": true,
+ "trailing": true,
+ "wsh": true
+ },
+ "pep8_ignore":
+ [
+ "E501"
+ ],
+ "perl_linter": "perlcritic",
+ "pyflakes_ignore":
+ [
+ ],
+ "pyflakes_ignore_import_*": true,
+ "sublimelinter": true,
+ "sublimelinter_delay": 0,
+ "sublimelinter_disable":
+ [
+ ],
+ "sublimelinter_executable_map":
+ {
+ },
+ "sublimelinter_fill_outlines": false,
+ "sublimelinter_gutter_marks": false,
+ "sublimelinter_notes": false,
+ "sublimelinter_objj_check_ascii": false,
+ "sublimelinter_popup_errors_on_save": false,
+ "sublimelinter_syntax_map":
+ {
+ "Python Django": "python"
+ },
+ "sublimelinter_wrap_find": true,
+ "syntax": "Packages/Python/Python.tmLanguage"
+ },
+ "translation.x": 0.0,
+ "translation.y": 57.0,
+ "zoom_level": 1.0
+ },
+ "type": "text"
+ },
+ {
+ "buffer": 2,
"file": "main.py",
"settings":
{
- "buffer_size": 0,
+ "buffer_size": 5103,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 3291,
+ 3291
+ ]
+ ],
+ "settings":
+ {
+ "annotations":
+ [
+ "TODO",
+ "README",
+ "FIXME"
+ ],
+ "csslint_options":
+ {
+ "adjoining-classes": "warning",
+ "box-model": true,
+ "box-sizing": "warning",
+ "compatible-vendor-prefixes": "warning",
+ "display-property-grouping": true,
+ "duplicate-background-images": "warning",
+ "duplicate-properties": true,
+ "empty-rules": true,
+ "errors": true,
+ "fallback-colors": "warning",
+ "floats": "warning",
+ "font-faces": "warning",
+ "font-sizes": "warning",
+ "gradients": "warning",
+ "ids": "warning",
+ "import": "warning",
+ "important": "warning",
+ "known-properties": true,
+ "outline-none": "warning",
+ "overqualified-elements": "warning",
+ "qualified-headings": "warning",
+ "regex-selectors": "warning",
+ "rules-count": "warning",
+ "shorthand": "warning",
+ "text-indent": "warning",
+ "unique-headings": "warning",
+ "universal-selector": "warning",
+ "vendor-prefix": true,
+ "zero-units": "warning"
+ },
+ "gjslint_ignore":
+ [
+ 110
+ ],
+ "gjslint_options":
+ [
+ ],
+ "javascript_linter": "jshint",
+ "jshint_options":
+ {
+ "browser": true,
+ "evil": true,
+ "regexdash": true,
+ "sub": true,
+ "trailing": true,
+ "wsh": true
+ },
+ "pep8_ignore":
+ [
+ "E501"
+ ],
+ "perl_linter": "perlcritic",
+ "pyflakes_ignore":
+ [
+ ],
+ "pyflakes_ignore_import_*": true,
+ "spell_check": true,
+ "sublimelinter": true,
+ "sublimelinter_delay": 0,
+ "sublimelinter_disable":
+ [
+ ],
+ "sublimelinter_executable_map":
+ {
+ },
+ "sublimelinter_fill_outlines": false,
+ "sublimelinter_gutter_marks": false,
+ "sublimelinter_notes": false,
+ "sublimelinter_objj_check_ascii": false,
+ "sublimelinter_popup_errors_on_save": false,
+ "sublimelinter_syntax_map":
+ {
+ "Python Django": "python"
+ },
+ "sublimelinter_wrap_find": true,
+ "syntax": "Packages/Python/Python.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 81.0,
+ "translation.y": 2442.0,
+ "zoom_level": 1.0
+ },
+ "type": "text"
+ },
+ {
+ "buffer": 3,
+ "file": "universals.py",
+ "settings":
+ {
+ "buffer_size": 484,
"regions":
{
},
@@ -96,13 +565,431 @@
],
"settings":
{
+ "annotations":
+ [
+ "TODO",
+ "README",
+ "FIXME"
+ ],
+ "csslint_options":
+ {
+ "adjoining-classes": "warning",
+ "box-model": true,
+ "box-sizing": "warning",
+ "compatible-vendor-prefixes": "warning",
+ "display-property-grouping": true,
+ "duplicate-background-images": "warning",
+ "duplicate-properties": true,
+ "empty-rules": true,
+ "errors": true,
+ "fallback-colors": "warning",
+ "floats": "warning",
+ "font-faces": "warning",
+ "font-sizes": "warning",
+ "gradients": "warning",
+ "ids": "warning",
+ "import": "warning",
+ "important": "warning",
+ "known-properties": true,
+ "outline-none": "warning",
+ "overqualified-elements": "warning",
+ "qualified-headings": "warning",
+ "regex-selectors": "warning",
+ "rules-count": "warning",
+ "shorthand": "warning",
+ "text-indent": "warning",
+ "unique-headings": "warning",
+ "universal-selector": "warning",
+ "vendor-prefix": true,
+ "zero-units": "warning"
+ },
+ "gjslint_ignore":
+ [
+ 110
+ ],
+ "gjslint_options":
+ [
+ ],
+ "javascript_linter": "jshint",
+ "jshint_options":
+ {
+ "browser": true,
+ "evil": true,
+ "regexdash": true,
+ "sub": true,
+ "trailing": true,
+ "wsh": true
+ },
+ "pep8_ignore":
+ [
+ "E501"
+ ],
+ "perl_linter": "perlcritic",
+ "pyflakes_ignore":
+ [
+ ],
+ "pyflakes_ignore_import_*": true,
+ "sublimelinter": true,
+ "sublimelinter_delay": 0,
+ "sublimelinter_disable":
+ [
+ ],
+ "sublimelinter_executable_map":
+ {
+ },
+ "sublimelinter_fill_outlines": false,
+ "sublimelinter_gutter_marks": false,
+ "sublimelinter_notes": false,
+ "sublimelinter_objj_check_ascii": false,
+ "sublimelinter_popup_errors_on_save": false,
+ "sublimelinter_syntax_map":
+ {
+ "Python Django": "python"
+ },
+ "sublimelinter_wrap_find": true,
"syntax": "Packages/Python/Python.tmLanguage"
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"type": "text"
+ },
+ {
+ "buffer": 4,
+ "file": "solarSystem.py",
+ "settings":
+ {
+ "buffer_size": 4416,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 4416,
+ 4416
+ ]
+ ],
+ "settings":
+ {
+ "annotations":
+ [
+ "TODO",
+ "README",
+ "FIXME"
+ ],
+ "csslint_options":
+ {
+ "adjoining-classes": "warning",
+ "box-model": true,
+ "box-sizing": "warning",
+ "compatible-vendor-prefixes": "warning",
+ "display-property-grouping": true,
+ "duplicate-background-images": "warning",
+ "duplicate-properties": true,
+ "empty-rules": true,
+ "errors": true,
+ "fallback-colors": "warning",
+ "floats": "warning",
+ "font-faces": "warning",
+ "font-sizes": "warning",
+ "gradients": "warning",
+ "ids": "warning",
+ "import": "warning",
+ "important": "warning",
+ "known-properties": true,
+ "outline-none": "warning",
+ "overqualified-elements": "warning",
+ "qualified-headings": "warning",
+ "regex-selectors": "warning",
+ "rules-count": "warning",
+ "shorthand": "warning",
+ "text-indent": "warning",
+ "unique-headings": "warning",
+ "universal-selector": "warning",
+ "vendor-prefix": true,
+ "zero-units": "warning"
+ },
+ "gjslint_ignore":
+ [
+ 110
+ ],
+ "gjslint_options":
+ [
+ ],
+ "javascript_linter": "jshint",
+ "jshint_options":
+ {
+ "browser": true,
+ "evil": true,
+ "regexdash": true,
+ "sub": true,
+ "trailing": true,
+ "wsh": true
+ },
+ "pep8_ignore":
+ [
+ "E501"
+ ],
+ "perl_linter": "perlcritic",
+ "pyflakes_ignore":
+ [
+ ],
+ "pyflakes_ignore_import_*": true,
+ "sublimelinter": true,
+ "sublimelinter_delay": 0,
+ "sublimelinter_disable":
+ [
+ ],
+ "sublimelinter_executable_map":
+ {
+ },
+ "sublimelinter_fill_outlines": false,
+ "sublimelinter_gutter_marks": false,
+ "sublimelinter_notes": false,
+ "sublimelinter_objj_check_ascii": false,
+ "sublimelinter_popup_errors_on_save": false,
+ "sublimelinter_syntax_map":
+ {
+ "Python Django": "python"
+ },
+ "sublimelinter_wrap_find": true,
+ "syntax": "Packages/Python/Python.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "type": "text"
+ },
+ {
+ "buffer": 5,
+ "file": "ships.py",
+ "settings":
+ {
+ "buffer_size": 457,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 111,
+ 111
+ ]
+ ],
+ "settings":
+ {
+ "annotations":
+ [
+ "TODO",
+ "README",
+ "FIXME"
+ ],
+ "csslint_options":
+ {
+ "adjoining-classes": "warning",
+ "box-model": true,
+ "box-sizing": "warning",
+ "compatible-vendor-prefixes": "warning",
+ "display-property-grouping": true,
+ "duplicate-background-images": "warning",
+ "duplicate-properties": true,
+ "empty-rules": true,
+ "errors": true,
+ "fallback-colors": "warning",
+ "floats": "warning",
+ "font-faces": "warning",
+ "font-sizes": "warning",
+ "gradients": "warning",
+ "ids": "warning",
+ "import": "warning",
+ "important": "warning",
+ "known-properties": true,
+ "outline-none": "warning",
+ "overqualified-elements": "warning",
+ "qualified-headings": "warning",
+ "regex-selectors": "warning",
+ "rules-count": "warning",
+ "shorthand": "warning",
+ "text-indent": "warning",
+ "unique-headings": "warning",
+ "universal-selector": "warning",
+ "vendor-prefix": true,
+ "zero-units": "warning"
+ },
+ "gjslint_ignore":
+ [
+ 110
+ ],
+ "gjslint_options":
+ [
+ ],
+ "javascript_linter": "jshint",
+ "jshint_options":
+ {
+ "browser": true,
+ "evil": true,
+ "regexdash": true,
+ "sub": true,
+ "trailing": true,
+ "wsh": true
+ },
+ "pep8_ignore":
+ [
+ "E501"
+ ],
+ "perl_linter": "perlcritic",
+ "pyflakes_ignore":
+ [
+ ],
+ "pyflakes_ignore_import_*": true,
+ "sublimelinter": true,
+ "sublimelinter_delay": 0,
+ "sublimelinter_disable":
+ [
+ ],
+ "sublimelinter_executable_map":
+ {
+ },
+ "sublimelinter_fill_outlines": false,
+ "sublimelinter_gutter_marks": false,
+ "sublimelinter_notes": false,
+ "sublimelinter_objj_check_ascii": false,
+ "sublimelinter_popup_errors_on_save": false,
+ "sublimelinter_syntax_map":
+ {
+ "Python Django": "python"
+ },
+ "sublimelinter_wrap_find": true,
+ "syntax": "Packages/Python/Python.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "type": "text"
+ }
+ ]
+ },
+ {
+ "selected": 0,
+ "sheets":
+ [
+ {
+ "buffer": 6,
+ "file": "client.py",
+ "settings":
+ {
+ "buffer_size": 3555,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 2332,
+ 2332
+ ]
+ ],
+ "settings":
+ {
+ "annotations":
+ [
+ "TODO",
+ "README",
+ "FIXME"
+ ],
+ "csslint_options":
+ {
+ "adjoining-classes": "warning",
+ "box-model": true,
+ "box-sizing": "warning",
+ "compatible-vendor-prefixes": "warning",
+ "display-property-grouping": true,
+ "duplicate-background-images": "warning",
+ "duplicate-properties": true,
+ "empty-rules": true,
+ "errors": true,
+ "fallback-colors": "warning",
+ "floats": "warning",
+ "font-faces": "warning",
+ "font-sizes": "warning",
+ "gradients": "warning",
+ "ids": "warning",
+ "import": "warning",
+ "important": "warning",
+ "known-properties": true,
+ "outline-none": "warning",
+ "overqualified-elements": "warning",
+ "qualified-headings": "warning",
+ "regex-selectors": "warning",
+ "rules-count": "warning",
+ "shorthand": "warning",
+ "text-indent": "warning",
+ "unique-headings": "warning",
+ "universal-selector": "warning",
+ "vendor-prefix": true,
+ "zero-units": "warning"
+ },
+ "gjslint_ignore":
+ [
+ 110
+ ],
+ "gjslint_options":
+ [
+ ],
+ "javascript_linter": "jshint",
+ "jshint_options":
+ {
+ "browser": true,
+ "evil": true,
+ "regexdash": true,
+ "sub": true,
+ "trailing": true,
+ "wsh": true
+ },
+ "pep8_ignore":
+ [
+ "E501"
+ ],
+ "perl_linter": "perlcritic",
+ "pyflakes_ignore":
+ [
+ ],
+ "pyflakes_ignore_import_*": true,
+ "sublimelinter": true,
+ "sublimelinter_delay": 0,
+ "sublimelinter_disable":
+ [
+ ],
+ "sublimelinter_executable_map":
+ {
+ },
+ "sublimelinter_fill_outlines": false,
+ "sublimelinter_gutter_marks": false,
+ "sublimelinter_notes": false,
+ "sublimelinter_objj_check_ascii": false,
+ "sublimelinter_popup_errors_on_save": false,
+ "sublimelinter_syntax_map":
+ {
+ "Python Django": "python"
+ },
+ "sublimelinter_wrap_find": true,
+ "syntax": "Packages/Python/Python.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 726.0,
+ "zoom_level": 1.0
+ },
+ "type": "text"
}
]
}
@@ -113,7 +1000,7 @@
},
"input":
{
- "height": 0.0
+ "height": 35.0
},
"layout":
{
@@ -124,11 +1011,18 @@
0,
1,
1
+ ],
+ [
+ 1,
+ 0,
+ 2,
+ 1
]
],
"cols":
[
0.0,
+ 0.463764990888,
1.0
],
"rows":
@@ -138,9 +1032,13 @@
]
},
"menu_visible": true,
+ "output.exec":
+ {
+ "height": 268.0
+ },
"replace":
{
- "height": 0.0
+ "height": 64.0
},
"save_all_on_build": true,
"select_file":
@@ -153,11 +1051,19 @@
},
"select_project":
{
- "height": 0.0,
+ "height": 500.0,
"selected_items":
[
+ [
+ "sandbox",
+ "/home/croxis/src/SandBox/sandbox.sublime-project"
+ ],
+ [
+ "",
+ "/home/croxis/src/SandBox/sandbox.sublime-project"
+ ]
],
- "width": 0.0
+ "width": 380.0
},
"show_minimap": true,
"show_open_files": false,
View
105 client.py
@@ -0,0 +1,105 @@
+import sandbox
+
+from pandac.PandaModules import loadPrcFileData
+loadPrcFileData("", "notify-level-ITF-ClientNetwork debug")
+from direct.directnotify.DirectNotify import DirectNotify
+log = DirectNotify().newCategory("ITF-ClientNetwork")
+
+from panda3d.core import QueuedConnectionManager, QueuedConnectionReader, ConnectionWriter, NetAddress, NetDatagram
+from direct.distributed.PyDatagram import PyDatagram
+from direct.distributed.PyDatagramIterator import PyDatagramIterator
+
+import protocol
+import solarSystem
+import universals
+
+class ClientNetworkSystem(sandbox.EntitySystem):
+ def init(self, port=2000, server="127.0.0.1", serverPort=1999, backlog=1000, compress=False):
+ self.packetCount = 0
+ self.port = port
+ self.serverPort = serverPort
+ self.serverIP = server
+ self.serverAddress = NetAddress()
+ self.serverAddress.setHost(server, serverPort)
+ self.cManager = QueuedConnectionManager()
+ self.cReader = QueuedConnectionReader(self.cManager, 0)
+ self.cWriter = ConnectionWriter(self.cManager, 0)
+
+ self.udpSocket = self.cManager.openUDPConnection(self.port)
+ self.cReader.addConnection(self.udpSocket)
+
+ self.startPolling()
+
+ def startPolling(self):
+ taskMgr.add(self.tskReaderPolling, "serverListenTask", -40)
+
+ def tskReaderPolling(self, taskdata):
+ if self.cReader.dataAvailable():
+ datagram = NetDatagram() # catch the incoming data in this instance
+ # Check the return value; if we were threaded, someone else could have
+ # snagged this data before we did
+ if self.cReader.getData(datagram):
+ myIterator = PyDatagramIterator(datagram)
+ msgID = myIterator.getUint8()
+
+ #If not in our protocol range then we just reject
+ if msgID < 0 or msgID > 200:
+ return taskdata.cont
+
+ #Order of these will need to be optimized later
+ #We now pull out the rest of our headers
+ remotePacketCount = myIterator.getUint8()
+ ack = myIterator.getUint8()
+ acks = myIterator.getUint16()
+ hashID = myIterator.getUint16()
+ sourceOfMessage = datagram.getConnection()
+
+ if msgID == protocol.LOGIN_ACCEPTED:
+ log.info("Login accepted")
+ universals.day = myIterator.getFloat32()
+ print "Day set to", universals.day
+ elif msgID == protocol.LOGIN_DENIED:
+ log.info("Login failed")
+ return taskdata.cont
+
+ def genBasicData(self, proto):
+ myPyDatagram = PyDatagram()
+ myPyDatagram.addUint8(proto)
+ myPyDatagram.addUint8(self.packetCount)
+ myPyDatagram.addUint8(0)
+ myPyDatagram.addUint16(0)
+ myPyDatagram.addUint16(0)
+ self.packetCount += 1
+ return myPyDatagram
+
+ def sendLogin(self, username, hashpassword):
+ datagram = self.genBasicData(protocol.LOGIN)
+ datagram.addString("User name")
+ datagram.addString("Hashed password")
+ log.debug("sending login")
+ self.sendData(datagram)
+
+ def sendData(self, datagram):
+ sent = self.cWriter.send(datagram, self.udpSocket, self.serverAddress)
+ while not sent:
+ print "resending"
+ sent = self.cWriter.send(datagram, self.udpSocket, self.serverAddress)
+
+log.info("Setting up Solar System Body Simulator")
+sandbox.addSystem(solarSystem.SolarSystemSystem(solarSystem.BaryCenter, solarSystem.Body, solarSystem.Star))
+
+def planetPositionDebug(task):
+ log.debug("===== Day: " + str(universals.day) + " =====")
+ for bod in sandbox.getSystem(solarSystem.SolarSystemSystem).bodies:
+ log.debug(bod.getName() + ": " + str(bod.getPos()))
+ return task.again
+
+taskMgr.doMethodLater(10, planetPositionDebug, "Position Debug")
+
+network = ClientNetworkSystem()
+sandbox.addSystem(network)
+
+
+
+taskMgr.doMethodLater(2, network.sendLogin, 'Task Name', extraArgs=["croxis", "pass"])
+sandbox.run()
View
236 main.py
@@ -23,8 +23,9 @@
from pandac.PandaModules import loadPrcFileData
#import Globals
-def usage(code, msg = ''):
- print >> sys.stderr, usageText % {'prog' : os.path.split(sys.argv[0])[1]}
+
+def usage(code, msg=''):
+ print >> sys.stderr, usageText % {'prog': os.path.split(sys.argv[0])[1]}
print >> sys.stderr, msg
sys.exit(code)
@@ -99,189 +100,78 @@ def usage(code, msg = ''):
from direct.directnotify.DirectNotify import DirectNotify
log = DirectNotify().newCategory("ITF")
-log.debug("Loading SandBox")
-import sys
-sys.path.append("/home/croxis/src")
-import SandBox
-
-from direct.stdpy.file import *
-from direct.task.Task import Task
-
-from panda3d.core import NodePath, Point3
+log.debug("Loading sandbox")
-import math
-from math import sin, cos, pi, radians, degrees, sqrt, atan2
+import sandbox
-import yaml
+from direct.stdpy.file import *
-import serverNet
+from panda3d.bullet import BulletRigidBodyNode, BulletSphereShape, BulletWorld
+from panda3d.core import Point3, Vec3
log.debug("Making room for globals")
-solarSystemRoot = 0
-# Connivance constant, number of seconds in an Earth day
-SECONDSINDAY = 86400
-
-# Time acceleration factor
-# Default is 31,536,000 (365.25*24*60), or the earth orbits the sun in one minute
-#TIMEFACTOR = 525969.162726
-# Factor where it orbits once every 5 minutes
-#TIMEFACTOR = 105193.832545
-# Once an hour
-#TIMEFACTOR = 8766.1527121
-# Once a day
-#TIMEFACTOR = 365.256363004
-# Realtime
-#TIMEFACTOR = 1
-TIMEFACTOR = 100.0
-
-# Julian day based on J2000.
-day = 9131.25
-bods = []
-
-
-class BaryCenter(NodePath):
- pass
-
-class Body(BaryCenter):
- period = 0
- mass = 1
- radius = 1
- kind = "solid"
- orbit = {}
-
-class Star(Body):
- kind = "star"
- absoluteM = 1
- spectralType = ""
-
-def getBodyPosition(entity, time):
- # Convert to radians
- M = radians(eval(entity.orbit['M'])(time))
- w = radians(eval(entity.orbit['w'])(time))
- i = radians(eval(entity.orbit['i'])(time))
- N = radians(eval(entity.orbit['N'])(time))
- a = entity.orbit['a']
- e = eval(entity.orbit['e'])(time)
-
- # Compute eccentric anomaly
- E = M + e * sin(M) * (1.0 + e * cos(M))
- if degrees(E) > 0.05:
- E = computeE(E, M, e)
- # http:#stjarnhimlen.se/comp/tutorial.html
- # Compute distance and true anomaly
- xv = a * (cos(E) - e)
- yv = a * (sqrt(1.0- e*e)* sin(E))
-
- v = atan2(yv, xv)
- r = sqrt(xv*xv + yv*yv)
-
- xh = r * ( cos(N) * cos(v+w) - sin(N) * sin(v+w) * cos(i) )
- yh = r * ( sin(N) * cos(v+w) + cos(N) * sin(v+w) * cos(i) )
- zh = r * ( sin(v+w) * sin(i) )
- position = Point3(xh, yh, zh)
- # If we are not a moon then our orbits are done in au. We need to convert to km
- # FIXME: Add moon body type
- if entity.type != 'moon':
- position = position*149598000
- return position
-
-
-def computeE(E0, M, e):
- '''Iterative function for a higher accuracy of E'''
- E1 = E0 - (E0 - e * sin(E0) - M) / (1 - e * cos(E0))
- if abs(abs(degrees(E1)) - abs(degrees(E0))) > 0.001:
- E1 = computeE(E1, M, e)
- return E1
-
-class SolarSystemSystem(SandBox.EntitySystem):
- def process(self, entity):
- '''Gets the xyz position of the body, relative to its parent, on the given day before/after the date of element. Units will be in AU'''
- component = 0
- try:
- component = entity.getComponent(BaryCenter)
- except:
- try:
- component = entity.getComponent(Body)
- except:
- component = entity.getComponent(Star)
- finally:
- if component.hasOrbit:
- component.setPos(getBodyPosition(component, day))
-
-
-def setupBodies(name):
- log.debug("Loading Solar System Bodies")
- stream = file("solarsystem.yaml", "r")
- solarDB = yaml.load(stream)
- stream.close()
- bodies = []
- solarSystemRoot = NodePath(name)
- for bodyName, bodyDB in solarDB[name].items():
- generateNode(bodies, bodyName, bodyDB, solarSystemRoot)
-
-
-def generateNode(bodies, name, DB, parentNode):
- log.debug("Setting up " + name)
- bodyEntity = SandBox.createEntity()
- if DB['type'] == 'solid':
- body = Body(name)
- elif DB['type'] == 'moon':
- body = Body(name)
- body.kind = "moon"
- elif DB['type'] == 'star':
- body = Star(name)
- body.absoluteM = DB['absolute magnitude']
- body.spectral = DB['spectral']
- elif DB['type'] == 'barycenter':
- body = BaryCenter(name)
-
- if DB['type'] != "barycenter":
- body.mass = DB['mass']
- body.radius = DB['radius']
- body.rotation = DB['rotation']
-
- if 'orbit' in DB:
- body.hasOrbit = True
- body.orbit = DB['orbit']
- body.period = DB['period']
- else:
- body.hasOrbit = False
-
- body.type = DB['type']
- body.reparentTo(parentNode)
-
-
- bodyEntity.addComponent(body)
-
- bodies.append(body)
- bods.append(body)
- log.info(name + " set Up")
-
- if 'bodies' in DB:
- for bodyName, bodyDB in DB['bodies'].items():
- generateNode(bodies, bodyName, bodyDB, body)
-
-
+import serverNet
+import ships
+import solarSystem
+import universals
log.info("Setting up Solar System Body Simulator")
-SandBox.addSystem(SolarSystemSystem(BaryCenter, Body, Star))
-setupBodies("Sol")
-
-def simulationTask(task):
- global day
- day += globalClock.getDt()/86400 * TIMEFACTOR
- return task.cont
+sandbox.addSystem(solarSystem.SolarSystemSystem(solarSystem.BaryCenter, solarSystem.Body, solarSystem.Star))
def planetPositionDebug(task):
- log.debug("===== Day: " + str(day) + " =====")
- for bod in bods:
+ log.debug("===== Day: " + str(universals.day) + " =====")
+ for bod in sandbox.getSystem(solarSystem.SolarSystemSystem).bodies:
log.debug(bod.getName() + ": " + str(bod.getPos()))
return task.again
-taskMgr.add(simulationTask, "Physics Simulation")
taskMgr.doMethodLater(10, planetPositionDebug, "Position Debug")
-log.info("Setting up network")
-SandBox.addSystem(serverNet.NetworkSystem())
+log.info("Setting up dynamic physics")
+
+
+class PhysicsSystem(sandbox.EntitySystem):
+ def init(self):
+ self.world = BulletWorld()
-SandBox.run()
+ def begin(self):
+ dt = globalClock.getDt()
+ self.world.doPhysics(dt)
+ #world.doPhysics(dt, 10, 1.0/180.0)
+
+sandbox.addSystem(PhysicsSystem(ships.BulletPhysicsComponent))
+
+log.info("Setting up network")
+sandbox.addSystem(serverNet.NetworkSystem())
+
+log.info("Setting up player-ship interface system")
+
+
+class PlayerShipsSystem(sandbox.EntitySystem):
+ #TODO: Add client --> network request
+ #TODO: Add automatic update
+ def newPlayerShip(account):
+ ship = sandbox.createEntity()
+ ship.addComponent(ships.PilotComponent())
+ component = ships.BulletPhysicsComponent()
+ component.bulletShape = BulletSphereShape(5)
+ component.node = BulletRigidBodyNode(account.name)
+ component.node.setMass(1.0)
+ component.node.addShape(component.bulletShape)
+ sandbox.getSystem(PhysicsSystem).world.attachRigidBody(component.node)
+ position = sandbox.getSystem(solarSystem.SolarSystemSystem).solarSystemRoot.find("Sol/Sol/Earth").getPos()
+ component.node.setPos(position + Point3(6671, 0, 0))
+ component.node.setLinearVelocity(Vec3(0, 7.72983, 0))
+ ship.addComponent(component)
+ component = ships.ThrustComponent()
+ ship.addComponent(component)
+ component = ships.HealthComponent()
+ ship.addComponent(component)
+
+ #TODO Transmit player's ship data
+ #TODO Broadcast new ship data
+ #TODO Prioritize updating new client of surroundings
+
+sandbox.addSystem(PlayerShipsSystem(ships.PilotComponent))
+
+
+sandbox.run()
View
BIN main.pyc
Binary file not shown.
View
47 protocol.py
@@ -0,0 +1,47 @@
+#Client to server even
+#Server to client odd
+#If both will probably be even
+
+# Packet structure
+# msgID = myIterator.getUint8()
+# remotePacketCount = myIterator.getUint8()
+# ack = myIterator.getUint8()
+# acks = myIterator.getUint16()
+# hashID = myIterator.getUint16()
+
+#Protocol space
+#0-99 common game elements
+#100-199 login and server handshaking and admin stuff
+
+ACK = 0
+POS_UPDATE = 1 # Position update for a given ship. 1 - 10 times a second
+THRUST_REQ = 2
+POS_PHYS_UPDATE = 3 # Full physics update for a given ship.
+# 1 per second unless a non predictive force (ie non gravity) is applied
+DATE_UPDATE = 5 # 1 per 5 seconds
+CHAT = 6
+
+NEW_SHIP = 9 # A ship has entered sensor range. All data is sent in this packet
+NEW_STATION = 11 # A station has entered sensor range.
+
+LOGIN = 100
+LOGIN_DENIED = 101
+LOGIN_ACCEPTED = 103
+
+CHAT = 104
+
+def genericPacket(key, packetCount=0):
+ myPyDatagram = PyDatagram()
+ myPyDatagram.addUint8(key)
+ myPyDatagram.addUint8(packetCount)
+ myPyDatagram.addUint8(0)
+ myPyDatagram.addUint16(0)
+ myPyDatagram.addUint16(0)
+ return myPyDatagram
+
+#Client to server datagram generators
+
+#Server to client datagram generators
+def loginAccepted():
+ datagram = genericPacket(LOGIN_ACCEPTED)
+ datagram.addString()
View
BIN protocol.pyc
Binary file not shown.
View
244 serverNet.py
@@ -1,11 +1,13 @@
import sys
sys.path.append('..')
-import SandBox
+import sandbox
from pandac.PandaModules import loadPrcFileData
-#loadPrcFileData("", "notify-level-ITF-Network debug")
+loadPrcFileData("", "notify-level-ITF-ServerNetwork debug")
from direct.directnotify.DirectNotify import DirectNotify
-log = DirectNotify().newCategory("ITF-Network")
+log = DirectNotify().newCategory("ITF-ServerNetwork")
+
+import datetime
from direct.directnotify.DirectNotify import DirectNotify
from direct.distributed.PyDatagram import PyDatagram
@@ -16,170 +18,126 @@
from panda3d.core import ConnectionWriter, NetAddress, NetDatagram, PointerToConnection, QueuedConnectionListener, QueuedConnectionManager, QueuedConnectionReader
+import protocol
+import universals
+
+accountEntities = {} #{"name": id}
+
class AccountComponent(object):
name = ""
passwordHash = ""
agentKeys = []
- connection = None
+ address = None
online = False
admin = False
mod = False
owner = False
-class NetworkSystem(SandBox.EntitySystem):
+class NetworkSystem(sandbox.EntitySystem):
def init(self, port=1999, backlog=1000, compress=False):
log.debug("Initing Network System")
self.accept("broadcastData", self.broadcastData)
self.port = port
self.backlog = backlog
self.compress = compress
-
+
self.cManager = QueuedConnectionManager()
- self.cListener = QueuedConnectionListener(self.cManager, 0)
self.cReader = QueuedConnectionReader(self.cManager, 0)
- self.cWriter = ConnectionWriter(self.cManager,0)
-
- self.activeConnections = {} # {connection: player}
- self.activePlayers = {} # {player: connection}
-
- self.connect(self.port, self.backlog)
- self.startPolling()
+ #self.cReader.setRawMode(True)
+ self.cWriter = ConnectionWriter(self.cManager, 0)
+ self.udpSocket = self.cManager.openUDPConnection(self.port)
+ self.cReader.addConnection(self.udpSocket)
+
+ self.activePlayers = [] # PlayerComponent
+ self.activeConnections = {} # {NetAddress : PlayerComponent}
+ self.lastAck = {} # {NetAddress: time}
- def connect(self, port, backlog=1000):
- # Bind to our socket
- tcpSocket = self.cManager.openTCPServerRendezvous(port, backlog)
- self.cListener.addConnection(tcpSocket)
+ self.startPolling()
def startPolling(self):
- taskMgr.add(self.tskListenerPolling, "serverListenTask", -40)
- taskMgr.add(self.tskDisconnectPolling, "serverDisconnectTask", -39)
- taskMgr.add(self.getData, "serverPollReader", -38)
-
- def tskListenerPolling(self, task):
- if self.cListener.newConnectionAvailable():
- rendezvous = PointerToConnection()
- netAddress = NetAddress()
- newConnection = PointerToConnection()
-
- if self.cListener.getNewConnection(rendezvous, netAddress, newConnection):
- newConnection = newConnection.p()
- #self.activeConnections.append(newConnection) # Remember connection
- self.cReader.addConnection(newConnection) # Begin reading connection
- #key = "requestLogin"
- #self.sendData(newConnection, key)
- print "New connection"
- return Task.cont
-
- def tskDisconnectPolling(self, task):
- while self.cManager.resetConnectionAvailable() == True:
- connPointer = PointerToConnection()
- self.cManager.getResetConnection(connPointer)
- connection = connPointer.p()
-
- # Remove the connection we just found to be "reset" or "disconnected"
- self.cReader.removeConnection(connection)
-
- # Loop through the activeConnections till we find the connection we just deleted
- # and remove it from our activeConnections list
- #for c in range(0, len(self.activeConnections)):
- #if self.activeConnections[c] == connection:
- #del self.activeConnections[c]
- #break
- #player = self.activeConnections
- del self.activePlayers[self.activeConnections[connection]]
- del self.activeConnections[connection]
-
- return Task.cont
-
+ taskMgr.add(self.tskReaderPolling, "serverListenTask", -40)
+ taskMgr.doMethodLater(10, self.activeCheck, "activeCheck")
+
+ def tskReaderPolling(self, taskdata):
+ if self.cReader.dataAvailable():
+ datagram = NetDatagram() # catch the incoming data in this instance
+ # Check the return value; if we were threaded, someone else could have
+ # snagged this data before we did
+ if self.cReader.getData(datagram):
+ myIterator = PyDatagramIterator(datagram)
+ msgID = myIterator.getUint8()
+
+ #If not in our protocol range then we just reject
+ if msgID < 0 or msgID > 200:
+ return taskdata.cont
+
+ self.lastAck[datagram.getAddress()] = datetime.datetime.now()
+ #TODO Switch to ip address and port
+
+ #Order of these will need to be optimized later
+ #We now pull out the rest of our headers
+ remotePacketCount = myIterator.getUint8()
+ ack = myIterator.getUint8()
+ acks = myIterator.getUint16()
+ hashID = myIterator.getUint16()
+
+ if msgID == protocol.LOGIN:
+ username = myIterator.getString()
+ password = myIterator.getString()
+ if username not in accountEntities:
+ entity = sandbox.createEntity()
+ component = AccountComponent()
+ component.name = username
+ component.passwordHash = password
+ if not accountEntities:
+ component.owner = True
+ component.address = datagram.getAddress()
+ entity.addComponent(component)
+ accountEntities[username] = entity.id
+ log.info("New player " + username + " logged in.")
+ #
+ self.activePlayers.append(component)
+ self.activeConnections[component.address] = component
+
+ myPyDatagram = PyDatagram()
+ myPyDatagram.addUint8(protocol.LOGIN_ACCEPTED)
+ #myPyDatagram.addUint8(packetCount)
+ myPyDatagram.addUint8(0)
+ myPyDatagram.addUint8(0)
+ myPyDatagram.addUint16(0)
+ myPyDatagram.addUint16(0)
+ #
+ myPyDatagram.addFloat32(universals.day)
+ self.send(myPyDatagram, datagram.getAddress())
+ #TODO: Send initial states?
+ else:
+ component = sandbox.entities[accountEntities[username]].getComponent(AccountComponent)
+ if component.passwordHash != password:
+ log.info("Player " + username + " has the wrong password.")
+ else:
+ component.connection = datagram.getConnection()
+ log.info("Player " + username + " logged in.")
+
+ return taskdata.cont
+
+ def activeCheck(self, task):
+ """Checks for last ack from all known active conenctions."""
+ for address, lastTime in self.lastAck.items():
+ if (datetime.datetime.now() - lastTime).seconds > 30:
+ component = self.activeConnections[address]
+ #TODO: Disconnect
+ return task.again
+
+ def send(self, datagram, connection):
+ self.cWriter.send(datagram, self.udpSocket, connection)
+
def broadcastData(self, key, *args):
# Broadcast data out to all activeConnections
+ for accountID in accountEntities.items():
+ sandbox.entities[accountID].getComponent()
for con in self.activePlayers.keys():
self.sendData(con, key, *args)
-
+
def processData(self, netDatagram):
myIterator = PyDatagramIterator(netDatagram)
return self.decode(myIterator.getString())
-
- def getClients(self):
- # return a list of all activeConnections
- return self.activeConnections
-
- def encode(self, data, compress=False):
- # encode(and possibly compress) the data with rencode
- return rencode.dumps(data)
-
- def decode(self, data):
- # decode(and possibly decompress) the data with rencode
- return rencode.loads(data)
-
- def sendData(self, player, key, *args):
- print "Server sends:", key, args
- myPyDatagram = PyDatagram()
- myPyDatagram.addString(self.encode([key, args]))
- self.cWriter.send(myPyDatagram, self.activePlayers[player])
-
- def lowSendData(self, connection, key, *args):
- """For cases, such as login and packet filtering, where the player/connection mapping may not exist."""
- print "Server low sends:", key, args
- myPyDatagram = PyDatagram()
- myPyDatagram.addString(self.encode([key, args]))
- self.cWriter.send(myPyDatagram, connection)
-
- def getData(self, task=None):
- data = []
- while self.cReader.dataAvailable():
- datagram = NetDatagram() # catch the incoming data in this instance
- # Check the return value; if we were threaded, someone else could have
- # snagged this data before we did
- if self.cReader.getData(datagram):
- #con = PointerToConnection()
- #con = datagram.getConnection()
- datum=self.processData(datagram)
- #me = {}
- #me["test"] = "got" + datum["test"]
- #self.sendData(me, con)
- data.append(datum)
- #return data
- #print "Server getdata", data
- if data:
- #messenger.send("gotData", data)
- #TODO: This is an expensive check. Need to think of a better way to structure this
- print "Server gets:", data[0][0], data[0][1]
- if data[0][0] == "login":
- self.loginManager(datagram.getConnection(), data[0][1][0], data[0][1][1])
- #print "got some data!", data[0][0], data[0][1]
- messenger.send(data[0][0], [self.activeConnections[datagram.getConnection()], data[0][1]])
- return Task.cont
-
- def loginManager(self, connection, username, password):
- playerEntity = None
- playerList = []
- owner = False
- for id in SandBox.systems[PlayerSystem].entities.keys():
- player = SandBox.components[id][PlayerComponent]
- log.debug("Login detected: Checking player " + player.name)
- playerList.append({"name": player.name}) #This is a dict in case we expand functionality later
- if player.name == username and player.password == password:
- playerEntity = player
- elif player.name == username and player.password != password:
- self.lowSendData(connection, "loginResponse", False, "Incorrect password")
- return
- if not playerEntity and not NEWPLAYERS:
- self.lowSendData(connection, "loginResponse", False, "Not Accepting new players")
- return
- elif not playerEntity and NEWPLAYERS:
- if not self.entities:
- owner = True
- playerEntity = SandBox.createEntity()
- playerComponent = PlayerComponent()
- playerEntity.addComponent(playerComponent)
- playerComponent.name = username
- playerComponent.password = password
- playerComponent.owner = owner
-
- self.activeConnections[connection] = playerEntity
- self.activePlayers[playerEntity] = connection
-
- self.sendData(playerEntity, "loginResponse", True, state.state)
- self.sendData(playerEntity, "playerList", playerList)
- self.broadcastData("playerJoined", username)
View
BIN serverNet.pyc
Binary file not shown.
View
24 ships.py
@@ -0,0 +1,24 @@
+'''Ship components'''
+
+class BulletPhysicsComponent(object):
+ '''Contains reference to bullet shape and node'''
+ bulletShape = None
+ node = None
+
+class AIPilotComponent(object):
+ ai = None
+
+class PilotComponent(object):
+ pass
+
+class ThrustComponent(object):
+ '''Maximum thrust values, in newtons'''
+ forward = 1
+ backwars = 1
+ lateral = 1
+ pitch = 1
+ yaw = 1
+ roll = 1
+
+class HealthComponent(object):
+ health = 100
View
BIN ships.pyc
Binary file not shown.
View
136 solarSystem.py
@@ -0,0 +1,136 @@
+"""Stuff needed for running a solar system"""
+from math import sin, cos, radians, degrees, sqrt, atan2
+
+import sandbox
+import yaml
+
+from panda3d.core import NodePath, Point3
+
+import universals
+
+#from pandac.PandaModules import loadPrcFileData
+#loadPrcFileData("", "notify-level-ITF debug")
+from direct.directnotify.DirectNotify import DirectNotify
+log = DirectNotify().newCategory("ITF-SolarSystem")
+
+
+class BaryCenter(NodePath):
+ pass
+
+
+class Body(BaryCenter):
+ period = 0
+ mass = 1
+ radius = 1
+ kind = "solid"
+ orbit = {}
+
+
+class Star(Body):
+ kind = "star"
+ absoluteM = 1
+ spectralType = ""
+
+
+class SolarSystemSystem(sandbox.EntitySystem):
+ """Generates celestial bodies and moves them in orbit"""
+ def getBodyPosition(self, entity, time):
+ """Returns celestial position relative to the parent"""
+ # Convert to radians
+ M = radians(eval(entity.orbit['M'])(time))
+ w = radians(eval(entity.orbit['w'])(time))
+ i = radians(eval(entity.orbit['i'])(time))
+ N = radians(eval(entity.orbit['N'])(time))
+ a = entity.orbit['a']
+ e = eval(entity.orbit['e'])(time)
+ # Compute eccentric anomaly
+ E = M + e * sin(M) * (1.0 + e * cos(M))
+ if degrees(E) > 0.05:
+ E = self.computeE(E, M, e)
+ # http:#stjarnhimlen.se/comp/tutorial.html
+ # Compute distance and true anomaly
+ xv = a * (cos(E) - e)
+ yv = a * (sqrt(1.0 - e * e) * sin(E))
+ v = atan2(yv, xv)
+ r = sqrt(xv * xv + yv * yv)
+ xh = r * (cos(N) * cos(v + w) - sin(N) * sin(v + w) * cos(i))
+ yh = r * (sin(N) * cos(v + w) + cos(N) * sin(v + w) * cos(i))
+ zh = r * (sin(v + w) * sin(i))
+ position = Point3(xh, yh, zh)
+ # If we are not a moon then our orbits are done in au.
+ # We need to convert to km
+ # FIXME: Add moon body type
+ if entity.type != 'moon':
+ position = position * 149598000
+ return position
+
+ def computeE(self, E0, M, e):
+ '''Iterative function for a higher accuracy of E'''
+ E1 = E0 - (E0 - e * sin(E0) - M) / (1 - e * cos(E0))
+ if abs(abs(degrees(E1)) - abs(degrees(E0))) > 0.001:
+ E1 = self.computeE(E1, M, e)
+ return E1
+
+ def process(self, entity):
+ '''Gets the xyz position of the body, relative to its parent, on the given day before/after the date of element. Units will be in AU'''
+ universals.day += globalClock.getDt() / 86400 * universals.TIMEFACTOR
+ component = 0
+ try:
+ component = entity.getComponent(BaryCenter)
+ except:
+ try:
+ component = entity.getComponent(Body)
+ except:
+ component = entity.getComponent(Star)
+ finally:
+ if component.hasOrbit:
+ component.setPos(self.getBodyPosition(component, universals.day))
+
+ def init(self, name='Sol'):
+ log.debug("Loading Solar System Bodies")
+ stream = file("solarsystem.yaml", "r")
+ solarDB = yaml.load(stream)
+ stream.close()
+ self.bodies = []
+ self.solarSystemRoot = NodePath(name)
+ for bodyName, bodyDB in solarDB[name].items():
+ self.generateNode(bodyName, bodyDB, self.solarSystemRoot)
+
+ def generateNode(self, name, DB, parentNode):
+ log.debug("Setting up " + name)
+ bodyEntity = sandbox.createEntity()
+ if DB['type'] == 'solid':
+ body = Body(name)
+ elif DB['type'] == 'moon':
+ body = Body(name)
+ body.kind = "moon"
+ elif DB['type'] == 'star':
+ body = Star(name)
+ body.absoluteM = DB['absolute magnitude']
+ body.spectral = DB['spectral']
+ elif DB['type'] == 'barycenter':
+ body = BaryCenter(name)
+
+ if DB['type'] != "barycenter":
+ body.mass = DB['mass']
+ body.radius = DB['radius']
+ body.rotation = DB['rotation']
+
+ if 'orbit' in DB:
+ body.hasOrbit = True
+ body.orbit = DB['orbit']
+ body.period = DB['period']
+ else:
+ body.hasOrbit = False
+
+ body.type = DB['type']
+ body.reparentTo(parentNode)
+ bodyEntity.addComponent(body)
+
+ self.bodies.append(body)
+ #bods.append(body)
+ log.info(name + " set Up")
+
+ if 'bodies' in DB:
+ for bodyName, bodyDB in DB['bodies'].items():
+ self.generateNode(bodyName, bodyDB, body)
View
BIN solarSystem.pyc
Binary file not shown.
View
20 universals.py
@@ -0,0 +1,20 @@
+
+solarSystemRoot = 0
+# Connivance constant, number of seconds in an Earth day
+SECONDSINDAY = 86400
+
+# Time acceleration factor
+# Default is 31,536,000 (365.25*24*60), or the earth orbits the sun in one minute
+#TIMEFACTOR = 525969.162726
+# Factor where it orbits once every 5 minutes
+#TIMEFACTOR = 105193.832545
+# Once an hour
+#TIMEFACTOR = 8766.1527121
+# Once a day
+#TIMEFACTOR = 365.256363004
+# Realtime
+#TIMEFACTOR = 1
+TIMEFACTOR = 100.0
+
+# Julian day based on J2000.
+day = 9131.25
View
BIN universals.pyc
Binary file not shown.

0 comments on commit 0e28274

Please sign in to comment.