Giter Site home page Giter Site logo

fddg's People

Contributors

devos50 avatar lfdversluis avatar nspruit avatar

Watchers

 avatar  avatar  avatar

fddg's Issues

Remove unacknowledged requests

Currently, requests from a server of which not all acks are received are never removed from the buffer. We should probably implement this using a timer for each request (of for instance 5s). When all acks are received, the timer should be stopped. When it expires, the request should be removed

Let clients select a random server

Now, all clients simple try to connect to the first server in the setup/servers.txt file. However, they should randomly pick one of them and try to connect to it. When this fails, it should randomly select another server.

Comments on current code

Here are some comments I have on the current codebase:

  • The package names (nl.tud) are not really unique. Something like nl.tud.dcs.fddg will be much better. (fixed in #29)
  • The code is currently not documented that well. I think that at least all interface methods (and preferably all other public methods as well) need a JavaDoc comment to inform each other about what the method does and why it is there (so it also documents the protocol). Now, you cannot see what some methods actually do without examining the code. (Fixed in #32)
  • With the current Main class you can only start all servers and clients on the same machine. However, we need to be able to distribute them across multiple machines to actually make it a distributed system. I suggest we do this by having a main method that only starts one server on the local machine. Then we can actually start each server on another machine. The same holds for the client processes. We can then also use scripts to for instance start x clients on one machine. (fixed in #31)
  • In the current Main class the IDs of the clients are randomly generated. This is not really correct as multiple clients can now have the same ID. Instead, the clients should receive their ID from the server (and not pick one themselves). (fixed in #39)
  • I think the GUI of a server should be optional so that you can also start one without a GUI. Currently, a new GUI is created for every server.(fixed in #31)
  • Why do we wait 5 seconds (and 1 second in the loop) in ServerProcess.run()? This is an example of where a comment should clarify this ;) (fixed in 2082fd7)
  • This (in ServerProcess.connect()) is not going to work when the clients run on different machines: ClientInterface ci = (ClientInterface) Naming.lookup("rmi://localhost:" + Main.SERVER_PORT + "/FDDGClient/" + playerId); (fixed in #47)
  • ServerProcess.broadcastFieldToConnectedPlayers() does not meet our design as the entire field is only sent once to each client (when he connects), so it will never be broadcast. This is probably related to issue #24
  • I think the XAction classes do not really represent game objects, so I would put them in another package. (fixed in #29)
  • For creating a copy of the path in Field.getDirectionToNearestDragon() you can better use the copy constructor of ArrayList (so new ArrayList<>(path)) instead of: ArrayList<Integer> updatedPath = new ArrayList<Integer>(path.size()); for(int pos : path){ updatedPath.add(pos); } (fixed in #29)
  • The Field.dragonRage() function should be replaced because this function only works when there is only one server. With multiple servers, the game state will become inconsistent. Perhaps only perform the rage on the players that have connected to the particular server. Then there is no need for sending messages to other servers. (fixed in #47)

RMI exception with different hosts (>=1 non-Windows)

With two hosts of which at least one does not run Windows when you start one client, you get the following exception:

INFO: Starting client
mrt 22, 2015 4:55:38 PM nl.tud.dcs.fddg.client.ClientProcess selectServer
INFO: Client 0 trying to connect to //localhost:1099/FDDGServer/0
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
        java.rmi.ConnectException: Connection refused to host: 127.0.1.1; nested exception is:
        java.net.ConnectException: Connection refused: connect
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:354)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$240(TCPTransport.java:683)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$17/1664698779.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
        at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
        at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
        at sun.rmi.server.UnicastRef.invoke(Unknown Source)
        at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
        at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
        at com.sun.proxy.$Proxy1.connect(Unknown Source)
        at nl.tud.dcs.fddg.client.ClientProcess.run(ClientProcess.java:112)
        at java.lang.Thread.run(Unknown Source)
Caused by: java.rmi.ConnectException: Connection refused to host: 127.0.1.1; nested exception is:
        java.net.ConnectException: Connection refused: connect
        at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
        at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
        at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:130)
        at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
        at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
        at com.sun.proxy.$Proxy0.performAction(Unknown Source)
        at nl.tud.dcs.fddg.server.ServerProcess.broadcastActionToServers(ServerProcess.java:363)
        at nl.tud.dcs.fddg.server.ServerProcess.connect(ServerProcess.java:234)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$240(TCPTransport.java:683)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$17/1664698779.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.ConnectException: Connection refused: connect
        at java.net.DualStackPlainSocketImpl.connect0(Native Method)
        at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.net.Socket.connect(Socket.java:589)
        at java.net.Socket.connect(Socket.java:538)
        at java.net.Socket.<init>(Socket.java:434)
        at java.net.Socket.<init>(Socket.java:211)
        at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
        at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
        at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
        ... 26 more

Incorrect dragonRage function

Now the dragonRage function looks as follows:

Set<Action> actionSet = new HashSet<Action>();

        for (int dragonId : dragonMap.keySet()) {
            Dragon d = dragonMap.get(dragonId);

            int dragonX = d.getxPos();
            int dragonY = d.getyPos();

            for (int i = 0; i < 4; i++) {
                int unitX = dragonX + dx[i];
                int unitY = dragonY + dy[i];

                if (isInBoard(unitX, unitY) && entities[unitY][unitX] instanceof Player && connectedPlayers.contains(entities[unitY][unitX].getUnitId())) {
                    Player p = (Player) entities[unitY][unitX];
                    p.setCurHitPoints(p.getCurHitPoints() - d.getAttackPower());

                    if (p.getCurHitPoints() <= 0) {
                        DeleteUnitAction dua = new DeleteUnitAction(p.getUnitId());
                        actionSet.add(dua);
                        removePlayer(p.getUnitId());
                    }

                    DamageAction da = new DamageAction(p.getUnitId(), d.getAttackPower());
                    actionSet.add(da);
                }
            }
        }
        return actionSet;

Dragon can attack players when the distance between them is at most 2. However, in the code above the for-loop doesn't do this correctly, as it only seems to search for players that are to right and above the dragon (and not also below or to the left). Also the range for searching these players is to big, as it can only be 2 at most (so horizontalDistance+vertDistance <= 2)

NPE in Field.isInRange()

After a while (with 100 clients), I get the following exception in multiple client processes:

Exception in thread "Thread-43" java.lang.NullPointerException
        at nl.tud.dcs.fddg.game.Field.isInRange(Field.java:108)
        at nl.tud.dcs.fddg.server.ServerProcess.attack(ServerProcess.java:128)
        at nl.tud.dcs.fddg.server.ServerProcess.performAction(ServerProcess.java:91)
        at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
        at sun.rmi.transport.Transport$1.run(Unknown Source)
        at sun.rmi.transport.Transport$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Unknown Source)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$240(Unknown Source)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$17/833442319.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
        at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
        at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
        at sun.rmi.server.UnicastRef.invoke(Unknown Source)
        at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
        at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
        at com.sun.proxy.$Proxy1.performAction(Unknown Source)
        at nl.tud.dcs.fddg.client.ClientProcess.run(ClientProcess.java:82)
        at java.lang.Thread.run(Unknown Source)

HealAction with only one client

Now, when you start only one client, it also sends requests for a HealAction to the server. However, this should not be possible with one client (as there is no other player to heal).

Exception is thrown when a client connects to one server (setup: 2 servers, 1 client)

java.rmi.NotBoundException: FDDGClient/0
    at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:136)
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:409)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
    at sun.rmi.transport.Transport$1.run(Transport.java:177)
    at sun.rmi.transport.Transport$1.run(Transport.java:174)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:275)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:252)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:378)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at java.rmi.Naming.lookup(Naming.java:101)
    at nl.tud.dcs.fddg.server.ServerProcess.reconnect(ServerProcess.java:326)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
    at sun.rmi.transport.Transport$1.run(Transport.java:177)
    at sun.rmi.transport.Transport$1.run(Transport.java:174)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

Repository ownership

I am perfectly fine with keeping the repository on my account until you want to open source it, but if anyone else has a slot for a private repository and wants to take ownership, let me know ๐Ÿ˜‰

Reconnecting to another server doesn't work correctly

In the current code, when the server a client was connected to crashes, it selects another server. However, this client is never added to the connectedPlayers map in the new server (as connect() is not called). In this way it is never attacked by dragons anymore

Broadcast end of game

When one of the servers decides to finish the game, it should broadcast this to all other servers and clients. The other servers and clients can then also finish the game (and exit the program).

Bug bug bug!

a player can hit a dragon (or vice versa) from a distance of at most 2 squares.

We implemented 1 :(

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.