Browse Source

*** empty log message ***

Dave Schuyler 24 years ago
parent
commit
6d8d15f893

+ 16 - 0
direct/src/directd/Sources.pp

@@ -0,0 +1,16 @@
+
+//#define LOCAL_LIBS \
+//    directbase
+#define OTHER_LIBS \
+    net:c linmath:c putil:c express:c panda:m pandaexpress:m dtoolconfig dtool
+#define WIN_SYS_LIBS $[WIN_SYS_LIBS] user32.lib //advapi32.lib
+
+//#define C++FLAGS -DWITHIN_PANDA
+
+#begin bin_target
+  #define TARGET directd
+
+  #define SOURCES \
+    directd.h directd.cxx
+
+#end bin_target

+ 439 - 0
direct/src/directd/directd.cxx

@@ -0,0 +1,439 @@
+// Filename: directd.cxx
+// Created by:  skyler 2002.04.08
+// Based on test_tcp_*.* by drose.
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+/*#include "directd.h"
+#include "pandaFramework.h"
+#include "queuedConnectionManager.h"*/
+
+#include <process.h>
+#include <Windows.h>
+#include "pandabase.h"
+
+#include "queuedConnectionManager.h"
+#include "queuedConnectionListener.h"
+#include "queuedConnectionReader.h"
+#include "connectionWriter.h"
+#include "netAddress.h"
+#include "connection.h"
+#include "datagramIterator.h"
+#include "netDatagram.h"
+
+#include "pset.h"
+
+
+
+namespace {
+  // The following is from an MSDN example:
+  
+  #define TA_FAILED 0
+  #define TA_SUCCESS_CLEAN 1
+  #define TA_SUCCESS_KILL 2
+  #define TA_SUCCESS_16 3
+
+  BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM lParam) {
+    DWORD dwID;
+    GetWindowThreadProcessId(hwnd, &dwID);
+    if(dwID == (DWORD)lParam) {
+       PostMessage(hwnd, WM_CLOSE, 0, 0);
+    }
+    return TRUE;
+  }
+
+  /*
+      DWORD WINAPI TerminateApp(DWORD dwPID, DWORD dwTimeout)
+
+      Purpose:
+        Shut down a 32-Bit Process (or 16-bit process under Windows 95)
+
+      Parameters:
+        dwPID
+           Process ID of the process to shut down.
+
+        dwTimeout
+           Wait time in milliseconds before shutting down the process.
+
+      Return Value:
+        TA_FAILED - If the shutdown failed.
+        TA_SUCCESS_CLEAN - If the process was shutdown using WM_CLOSE.
+        TA_SUCCESS_KILL - if the process was shut down with
+           TerminateProcess().
+        NOTE:  See header for these defines.
+  */ 
+  DWORD WINAPI
+  TerminateApp(DWORD dwPID, DWORD dwTimeout) {
+    HANDLE   hProc;
+    DWORD   dwRet;
+
+    // If we can't open the process with PROCESS_TERMINATE rights,
+    // then we give up immediately.
+    hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, dwPID);
+    if(hProc == NULL) {
+       return TA_FAILED;
+    }
+
+    // TerminateAppEnum() posts WM_CLOSE to all windows whose PID
+    // matches your process's.
+    EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID);
+
+    // Wait on the handle. If it signals, great. If it times out,
+    // then you kill it.
+    if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0) {
+       dwRet=(TerminateProcess(hProc,0)?TA_SUCCESS_KILL:TA_FAILED);
+    } else {
+       dwRet = TA_SUCCESS_CLEAN;
+    }
+    CloseHandle(hProc);
+
+    return dwRet;
+  }
+
+}
+
+
+class DirectD {
+public:
+  DirectD();
+  ~DirectD();
+  
+  void set_host_name(const string& host_name);
+  void set_port(int port);
+  void spawn_background_server();
+  
+  void run_server();
+  void run_client();
+  void run_controller();
+  
+  void send_start_app(const string& cmd);
+  void start_app(const string& cmd);
+  
+  void send_kill_app(const string& pid);
+  void kill_app();
+
+protected:
+  QueuedConnectionManager _cm;
+  string _host_name;
+  int _port;
+  intptr_t _app_pid;
+  bool _controller;
+  bool _verbose;
+};
+
+
+
+
+DirectD::DirectD() :
+    _host_name("localhost"),
+    _port(8001), _app_pid(0),
+    _controller(false), _verbose(false) {
+}
+
+DirectD::~DirectD() {
+
+}
+
+void
+DirectD::set_host_name(const string& host_name) {
+  _host_name=host_name;
+}
+
+void
+DirectD::set_port(int port) {
+  _port=port;
+}
+
+void
+DirectD::send_start_app(const string& cmd) {
+  
+}
+
+void
+DirectD::start_app(const string& cmd) {
+  #if 0 //[
+  const char* args[]={
+    cmd.c_str(),
+    0
+  };
+  _app_pid=_spawnvp(_P_NOWAIT, args[0], args);
+  cerr<<"started app "<<_app_pid<<" errno "<<errno<<endl;
+  #else //][
+  PROCESS_INFORMATION piProcInfo; 
+  STARTUPINFO siStartInfo; 
+  ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
+  ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
+  siStartInfo.cb = sizeof(STARTUPINFO); 
+  if (CreateProcess(NULL, "calc.exe", 
+      0, 0, 1, NORMAL_PRIORITY_CLASS, 
+      0, 0, &siStartInfo, &piProcInfo)) {
+    cerr<<"CreateProcess worked"<<endl;
+    _app_pid=piProcInfo.dwProcessId;
+  } else {
+    cerr<<"CreateProcess failed"<<endl;
+  }
+  #endif //]
+}
+
+void
+DirectD::send_kill_app(const string& cmd) {
+  
+}
+
+void
+DirectD::kill_app() {
+  if (_app_pid) {
+    cerr<<"trying k "<<_app_pid<<endl;
+    HWND h=(HWND&)_app_pid;
+    //::CloseWindow(h);
+    //SendMessage(h, WM_CLOSE, 0, 0);
+    //TerminateProcess(h, 1);
+    
+    //int status=0;
+    //status = kill(_app_pid, SIGKILL);
+    //waitpid(_app_pid, &status, 0);
+    
+    TerminateApp(_app_pid, 1000);
+  }
+}
+
+void
+DirectD::spawn_background_server() {
+  const char* args[]={
+    "directd",
+    "-s",
+    _host_name.c_str(),
+    "8001",
+    0
+  };
+  intptr_t e=_spawnv(_P_NOWAIT, args[0], args);
+  cerr<<"spawn complete "<<e<<" errno "<<errno<<endl;
+}
+
+void
+DirectD::run_server() {
+  if (_verbose) cerr<<"server"<<endl;
+
+  PT(Connection) rendezvous = _cm.open_TCP_server_rendezvous(_port, 5);
+
+  if (rendezvous.is_null()) {
+    nout << "Cannot grab port " << _port << ".\n";
+    exit(1);
+  }
+
+  if (_verbose) nout << "Listening for connections on port " << _port << "\n";
+
+  QueuedConnectionListener listener(&_cm, 0);
+  listener.add_connection(rendezvous);
+
+  typedef pset< PT(Connection) > Clients;
+  Clients clients;
+
+  QueuedConnectionReader reader(&_cm, 1);
+  ConnectionWriter writer(&_cm, 1);
+
+  bool shutdown = false;
+  while (!shutdown) {
+    // Check for new clients.
+    while (listener.new_connection_available()) {
+      PT(Connection) rv;
+      NetAddress address;
+      PT(Connection) new_connection;
+      if (listener.get_new_connection(rv, address, new_connection)) {
+        if (_verbose) nout << "Got connection from " << address << "\n";
+        reader.add_connection(new_connection);
+        clients.insert(new_connection);
+      }
+    }
+
+    // Check for reset clients.
+    while (_cm.reset_connection_available()) {
+      PT(Connection) connection;
+      if (_cm.get_reset_connection(connection)) {
+        nout << "Lost connection from "
+             << connection->get_address() << "\n";
+        clients.erase(connection);
+        _cm.close_connection(connection);
+      }
+    }
+
+    // Process all available datagrams.
+    while (reader.data_available()) {
+      NetDatagram datagram;
+      if (reader.get_data(datagram)) {
+        nout << "Got datagram " /*<< datagram <<*/ "from "
+             << datagram.get_address() << ", sending to "
+             << clients.size() << " clients.\n";
+        if (_verbose) datagram.dump_hex(nout);
+
+        Clients::iterator ci;
+        for (ci = clients.begin(); ci != clients.end(); ++ci) {
+          writer.send(datagram, (*ci));
+        }
+
+        if (datagram.get_length() <= 1) {
+          /*
+          // An empty datagram means to close the connection.
+          PT(Connection) connection = datagram.get_connection();
+          if (connection.is_null()) {
+            nout << "Empty datagram from a null connection.\n";
+          } else {
+            nout << "Closing connection from "
+                 << connection->get_address() << "\n";
+            clients.erase(connection);
+            _cm.close_connection(connection);
+            nout << "Closed " << connection << "\n";
+          }
+          */
+
+          // No, an empty datagram means to shut down the server.
+          shutdown = true;
+        }
+      }
+    }
+
+    // Yield the timeslice before we poll again.
+    PR_Sleep(PR_MillisecondsToInterval(100));
+  }
+}
+
+void
+DirectD::run_client() {
+  if (!_controller) {
+    cerr<<"client"<<endl;
+  }
+
+  NetAddress host;
+  if (!host.set_host(_host_name, _port)) {
+    nout << "Unknown host: " << _host_name << "\n";
+  }
+
+  PT(Connection) c = _cm.open_TCP_client_connection(host, 5000);
+
+  if (c.is_null()) {
+    nout << "No connection.\n";
+    exit(1);
+  }
+
+  nout << "Successfully opened TCP connection to " << _host_name
+       << " on port "
+       << c->get_address().get_port() << " and IP "
+       << c->get_address() << "\n";
+
+  QueuedConnectionReader reader(&_cm, 0);
+  reader.add_connection(c);
+  ConnectionWriter writer(&_cm, 0);
+
+  bool lost_connection = false;
+
+  while (!cin.fail() && !lost_connection) {
+    NetDatagram datagram;
+    if (_controller) {
+      cout << "directd send: " << flush;
+      string d;
+      cin >> d;
+      datagram.add_string(d);
+      // Send the datagram.
+      writer.send(datagram, c);
+    }
+
+    // Check for a lost connection.
+    while (_cm.reset_connection_available()) {
+      PT(Connection) connection;
+      if (_cm.get_reset_connection(connection)) {
+        nout << "Lost connection from "
+             << connection->get_address() << "\n";
+        _cm.close_connection(connection);
+        if (connection == c) {
+          lost_connection = true;
+        }
+      }
+    }
+
+    // Now poll for new datagrams on the socket.
+    while (reader.data_available()) {
+      if (reader.get_data(datagram)) {
+        nout << "Got datagram " /*<< datagram*/ << "from "
+             << datagram.get_address() << "\n";
+        datagram.dump_hex(nout);
+        if (!_controller) {
+          DatagramIterator di(datagram);
+          string cmd=di.get_string();
+          cerr<<"cmd="<<cmd<<endl;
+          switch (cmd[0]) {
+          case 's':
+            start_app("calc");
+            break;
+          case 'k':
+            kill_app();
+            break;
+          default:
+            cerr<<"unknown command: "<<cmd<<endl;
+          }
+        }
+      }
+    }
+  }
+  nout << "Exiting\n";
+}
+
+void
+DirectD::run_controller() {
+  cerr<<"controller"<<endl;
+  _controller=true;
+  run_client();
+}
+
+
+int
+main(int argc, char *argv[]) {
+  if (argc > 1 && strcmp(argv[1], "--help")==0) {
+    cerr<<"directd [-c <host>] <port>\n"
+    "    -c        run as client (else run as server).\n"
+    "    host      e.g. localhost\n"
+    "    port      default 8001\n";
+    return 1;
+  }
+
+  cerr<<"directd"<<endl;
+  DirectD directd;
+  if (argc >= 3) {
+    string host=argv[argc-2];
+    directd.set_host_name(host);
+  }
+  char run_as=' ';
+  if (argc > 1) {
+    directd.set_port(atoi(argv[argc-1]));
+    if (strlen(argv[1]) > 1 && argv[1][0] == '-') {
+      run_as=argv[1][1];
+    }
+  }
+  switch (run_as) {
+  case 's':
+    directd.run_server();
+    break;
+  case 'c':
+    directd.run_client();
+    break;
+  default:
+    directd.spawn_background_server();
+    PR_Sleep(PR_MillisecondsToInterval(1000));
+    directd.run_controller();
+    break;
+  }
+  
+  return 0;
+}

+ 1 - 0
direct/src/directd/directd.h

@@ -0,0 +1 @@
+// directd.h

+ 49 - 0
direct/src/directd/directd.py

@@ -0,0 +1,49 @@
+#!python
+"""directd stuff"""
+
+from AIBaseGlobal import *
+import DirectNotifyGlobal
+import Datagram
+import DatagramIterator
+
+
+print "hello"
+
+
+class DirectDServer:
+    notify = DirectNotifyGlobal.directNotify.newCategory("DirectD")
+
+    def __init__(self):
+        pass
+
+    def connect(self, ip, port, timeout=35000):
+        self.qcm=QueuedConnectionManager()
+        self.tcpConn=self.qcm.openTCPClientConnection(ip, port, timeout)
+        
+        if self.tcpConn == None:
+            # Bad Connection
+            print "noConnection"
+        else:
+            # Good Connection
+            # Set up connection reader and writer
+            self.qcr=QueuedConnectionReader(self.qcm, 0)
+            self.qcr.addConnection(self.tcpConn)
+            self.cw=ConnectionWriter(self.qcm, 0)
+            while 1:
+                s=raw_input("send: ")
+                d=Datagram.Datagram()
+                d.addString(s)
+                self.cw.send(d, self.tcpConn)
+                while self.qcr.dataAvailable():
+                    nd=NetDatagram()
+                    self.qcr.getData(nd)
+                    print "address", nd.getAddress().getIp()
+                    nd.dumpHex(ostream)
+            #self.startReaderPollTask()
+            
+            # Register our channel
+            #self.registerForChannel(self.ourChannel)
+
+def foo():
+    dds = DirectDServer()
+    dds.connect("127.0.0.1", 8000)