Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: marauroa/game/RPServerManager.java


1   /* $Id: RPServerManager.java,v 1.31 2003/12/12 16:18:24 arianne_rpg Exp $ */
2   /***************************************************************************
3    *                      (C) Copyright 2003 - Marauroa                      *
4    ***************************************************************************
5    ***************************************************************************
6    *                                                                         *
7    *   This program is free software; you can redistribute it and/or modify  *
8    *   it under the terms of the GNU General Public License as published by  *
9    *   the Free Software Foundation; either version 2 of the License, or     *
10   *   (at your option) any later version.                                   *
11   *                                                                         *
12   ***************************************************************************/
13  package marauroa.game;
14  
15  import java.util.*;
16  import java.io.*;
17  import java.net.*;
18  
19  import marauroa.net.*;
20  import marauroa.*;
21  
22  /** This class is responsible for adding actions to scheduler, and to build and 
23   *  sent perceptions */
24  class RPServerManager extends Thread
25    {
26    /** We send 1 TOTAL perception each TOTAL_PERCEPTION_RELATION DELTA perceptions */
27    private final static int TOTAL_PERCEPTION_RELATION=10;
28    
29    /** The thread will be running while keepRunning is true */
30    private boolean keepRunning;
31    /** isFinished is true when the thread has really exited. */
32    private boolean isfinished;
33    /** The time elapsed between 2 turns. */
34    private long turnDuration;
35    
36    /** The scheduler needed to organize actions */
37    private RPScheduler scheduler;
38    /** The ruleProcessor that the scheduler will use to execute the actions */
39    private RPRuleProcessor ruleProcessor;
40    /** The place where the objects are stored */
41    private RPZone zone;
42    
43    /** The networkServerManager so that we can send perceptions */
44    private NetworkServerManager netMan;
45    /** The PlayerEntryContainer so that we know where to send perceptions */
46    private PlayerEntryContainer playerContainer;
47    
48    
49    /** Constructor 
50     *  @param netMan the NetworkServerManager so that we can send message */
51    public RPServerManager(NetworkServerManager netMan)
52      {
53      super("RPServerManager");
54      
55      marauroad.trace("RPServerManager",">");
56     
57      try
58        {
59        keepRunning=true;
60        isfinished=false;
61        
62        scheduler=new RPScheduler();
63        playerContainer=PlayerEntryContainer.getContainer();    
64        this.netMan=netMan;
65        
66        Configuration conf=Configuration.getConfiguration();
67        Class zoneClass=Class.forName(conf.get("rp_RPZoneClass"));
68        zone=(RPZone)zoneClass.newInstance();
69        
70        Class ruleProcessorClass=Class.forName(conf.get("rp_RPRuleProcessorClass"));
71        ruleProcessor=(RPRuleProcessor)ruleProcessorClass.newInstance();
72        ruleProcessor.setContext(zone);
73        
74        String duration =conf.get("rp_turnDuration");
75        turnDuration = Long.parseLong(duration);
76        
77        start();
78        }
79      catch(Exception e)
80        {
81        marauroad.trace("RPServerManager","X",e.getMessage());
82        marauroad.trace("RPServerManager","!","ABORT: Unable to create RPZone and RPRuleProcessor instances");
83        System.exit(-1);
84        }
85      finally
86        {    
87        marauroad.trace("RPServerManager","<");
88        }
89      }
90    
91    /** Constructor 
92     *  @param netMan the NetworkServerManager so that we can send message */
93    public RPServerManager(NetworkServerManager netMan, RPZone zone, RPRuleProcessor ruleProcessor, long turnDuration)
94      {
95      super("RPServerManager");
96      
97      marauroad.trace("RPServerManager",">");
98     
99      try
100       {
101       keepRunning=true;
102       isfinished=false;
103       
104       scheduler=new RPScheduler();
105       playerContainer=PlayerEntryContainer.getContainer();    
106       this.netMan=netMan;
107       this.zone=zone;
108       this.ruleProcessor=ruleProcessor;
109       this.turnDuration=turnDuration;
110       
111       start();
112       }
113     finally
114       {    
115       marauroad.trace("RPServerManager","<");
116       }
117     }
118 
119   public void finish()
120     {
121     marauroad.trace("RPServerManager::finish",">");
122     keepRunning=false;
123 
124     while(isfinished==false)
125       {
126       try
127         {
128         Thread.sleep(1000);
129         }
130       catch(java.lang.InterruptedException e)
131         {
132         }
133       }
134 
135     marauroad.trace("RPServerManager::finish","<");
136     }
137   
138   public void addRPAction(RPAction action) throws RPScheduler.ActionInvalidException
139     {
140     marauroad.trace("RPServerManager::addRPAction",">");
141     try
142       {
143       marauroad.trace("RPServerManager::addRPAction","D","Added action: "+action.toString());
144       scheduler.addRPAction(action);
145       }
146     finally
147       {
148       marauroad.trace("RPServerManager::addRPAction","<");
149       }
150     }
151     
152   public void addRPObject(RPObject object) throws RPZone.RPObjectInvalidException
153     {
154     marauroad.trace("RPServerManager::addRPObject",">");
155     try
156       {
157       marauroad.trace("RPServerManager::addRPObject","D","Added object: "+object.toString());
158       zone.add(object);
159       }
160     finally
161       {
162       marauroad.trace("RPServerManager::addRPObject","<");
163       }
164     }
165   
166   public RPObject getRPObject(RPObject.ID id) throws RPZone.RPObjectNotFoundException
167     {
168     marauroad.trace("RPServerManager::getRPObject",">");
169     
170     try
171       {
172       return zone.get(id);
173       }
174     finally
175       {
176       marauroad.trace("RPServerManager::getRPObject","<");
177       }
178     }
179   
180   public boolean hasRPObject(RPObject.ID id)
181     {
182     marauroad.trace("RPServerManager::hasRPObject",">");
183     
184     try
185       {
186       return zone.has(id);
187       }
188     finally
189       {
190       marauroad.trace("RPServerManager::hasRPObject","<");      
191       }
192     }
193   
194   public RPObject removeRPObject(RPObject.ID id) throws RPZone.RPObjectNotFoundException
195     {
196     marauroad.trace("RPServerManager::removeRPObject",">");
197     
198     try
199       {
200       marauroad.trace("RPServerManager::removeRPObject","D","Removed object: "+id.toString());
201       return zone.remove(id);
202       }
203     finally
204       {
205       marauroad.trace("RPServerManager::removeRPObject","<");
206       }
207     }
208 
209   private int deltaPerceptionSend=0;
210   
211   private void buildPerceptions()
212     {
213     marauroad.trace("RPServerManager::buildPerceptions",">");
214     List playersToRemove=new LinkedList();
215     
216     try
217       {
218       playerContainer.getLock().requestReadLock();
219 
220       ++deltaPerceptionSend;
221       PlayerEntryContainer.ClientIDIterator it=playerContainer.iterator();
222     
223       
224       while(it.hasNext())
225         {
226         int clientid=it.next();
227         
228         try
229           {
230           if(playerContainer.getRuntimeState(clientid)==playerContainer.STATE_GAME_BEGIN)
231             {
232             InetSocketAddress source=playerContainer.getInetSocketAddress(clientid);
233             RPZone.Perception perception;
234             if(deltaPerceptionSend>TOTAL_PERCEPTION_RELATION)
235               {
236               perception=zone.getPerception(playerContainer.getRPObjectID(clientid),RPZone.Perception.TOTAL);
237               deltaPerceptionSend=0;
238               }
239             else
240               {
241               perception=zone.getPerception(playerContainer.getRPObjectID(clientid),RPZone.Perception.DELTA);
242               }
243             
244             Message messages2cPerception=new MessageS2CPerception(source, perception.modifiedList, perception.deletedList);
245             netMan.addMessage(messages2cPerception);            
246             }
247             
248           if(playerContainer.timedout(clientid))
249             {
250             playersToRemove.add(new Integer(clientid));
251             }          
252           }
253         catch(Exception e)
254           {
255           marauroad.trace("RPServerManager::buildPerceptions","X",e.getMessage());
256           }
257         }
258 
259       playerContainer.getLock().releaseLock();
260 
261     /* Removing the players is a write operation */
262       playerContainer.getLock().requestWriteLock();
263       removeTimedoutPlayers(playersToRemove);
264       playerContainer.getLock().releaseLock();
265       }      
266     finally
267       {
268       marauroad.trace("RPServerManager::buildPerceptions","<");
269       }
270     }
271 
272   private void removeTimedoutPlayers(List playersToRemove)    
273     {
274     marauroad.trace("RPServerManager::removeTimedoutPlayers",">");
275 
276     try
277       {
278       Iterator it_removed=playersToRemove.iterator();
279       while(it_removed.hasNext())
280         {
281         int clientid=((Integer)it_removed.next()).intValue();
282      
283         RPObject.ID id=playerContainer.getRPObjectID(clientid);    
284         RPObject object=removeRPObject(id);
285       
286         /* NOTE: Set the Object so that it is stored in Database */
287         playerContainer.setRPObject(clientid,object);  
288         playerContainer.removeRuntimePlayer(clientid);
289 
290         marauroad.trace("RPServerManager::removeTimedoutPlayers","D","Removed player ("+clientid+")");
291         }
292       }
293     catch(Exception e)
294       {
295       marauroad.trace("RPServerManager::removeTimedoutPlayers","!","Can't remove a player(-not available-) that timedout");
296       System.exit(-1);
297       }
298     finally
299       {
300       marauroad.trace("RPServerManager::removeTimedoutPlayers","<");
301       }
302     }
303   
304   public void run()
305     {
306     marauroad.trace("RPServerManager::run",">");
307     
308     while(keepRunning)
309       {
310       scheduler.visit(ruleProcessor);      
311       buildPerceptions();
312 
313       try
314         {
315         Thread.sleep(turnDuration);
316         }
317       catch(InterruptedException e)
318         {
319         }
320 
321       scheduler.nextTurn();      
322       ruleProcessor.nextTurn();
323       zone.nextTurn();      
324       }
325       
326     isfinished=true;    
327     marauroad.trace("RPServerManager::run","<");
328     }
329   }
330