Skip to content

Commit

Permalink
WIP - observability check rewrite.
Browse files Browse the repository at this point in the history
  • Loading branch information
lhunath committed Feb 25, 2014
1 parent 709f632 commit d79c73f
Show file tree
Hide file tree
Showing 22 changed files with 295 additions and 150 deletions.
44 changes: 44 additions & 0 deletions .idea/codeStyleSettings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/dictionaries/lhunath.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions .idea/inspectionProfiles/Lhunath.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.lyndir.omicron.api.model;

import com.lyndir.omicron.api.util.Maybe;


/**
* @author lhunath, 2/25/2014
*/
public interface GameObservable {

/**
* @return The player that has control over this observable, if any.
*/
Maybe<? extends IPlayer> checkOwner();

/**
* @return The observable's location or {@link Maybe#unknown()} if the current player doesn't own the observable and none of its game objects can observe it.
*/
Maybe<? extends ITile> checkLocation()
throws Security.NotAuthenticatedException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
public interface GameObserver {

/**
* Check whether the current object can observe the tile at the given location.
* Check whether the current object can observe given observable.
*
* @param location The tile that this observer is trying to see.
* @param observable The observable that this observer is trying to see.
*
* @return true if the current player is allowed to know and the given tile is visible to this observer.
* @return true if the current player is able and allowed to observe the target.
*/
@Authenticated
Maybool canObserve(@Nonnull ITile location)
Maybool canObserve(@Nonnull GameObservable observable)
throws Security.NotAuthenticatedException;

/**
Expand All @@ -34,11 +34,4 @@ Maybool canObserve(@Nonnull ITile location)
@Authenticated
Iterable<? extends ITile> listObservableTiles()
throws Security.NotAuthenticatedException, Security.NotObservableException;

/**
* @return The player that has control over this observer, if any.
*/
@Nonnull
// TODO: This should return a Maybe to avoid being able to detect ownership changes on objects that are not observable.
Optional<? extends IPlayer> getOwner();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableCollection;
import com.lyndir.lhunath.opal.system.util.PredicateNN;
import com.lyndir.omicron.api.util.Maybe;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand All @@ -16,7 +15,7 @@
*
* @author lhunath
*/
public interface IGameObject extends GameObserver {
public interface IGameObject extends GameObserver, GameObservable {

@Nonnull
IGameObjectController<? extends IGameObject> getController();
Expand All @@ -28,9 +27,6 @@ boolean isOwnedByCurrentPlayer()

IGame getGame();

Maybe<? extends ITile> checkLocation()
throws NotAuthenticatedException;

IUnitType getType();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ public interface IPlayer extends GameObserver {
@Nonnull
IPlayerController getController();

@Override
Maybool canObserve(@Nonnull ITile location)
throws Security.NotAuthenticatedException;

int getPlayerID();

boolean hasKey(PlayerKey playerKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public interface IPlayerController extends GameObserver {
*
* @return A list of game objects owned by this controller's player.
*/
ImmutableCollection<? extends IGameObject> listObjects()
ImmutableSet<? extends IGameObject> listObjects()
throws NotAuthenticatedException;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ public IGameObjectController<? extends IGameObject> getController() {

@Nonnull
@Override
public Optional<? extends IPlayer> getOwner() {
return core.getOwner();
public Optional<? extends IPlayer> checkOwner() {
return core.checkOwner();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

package com.lyndir.omicron.api.model;

import static com.google.common.base.Preconditions.checkArgument;
import static com.lyndir.omicron.api.model.error.ExceptionUtils.*;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.lyndir.lhunath.opal.system.util.Job;
import com.lyndir.lhunath.opal.system.util.ObjectUtils;
Expand Down Expand Up @@ -76,13 +78,13 @@ static void playerRun(final IPlayer jobPlayer, final Runnable job) {
}

public static void authenticate(final IPlayer currentPlayer, final PlayerKey playerKey) {
Preconditions.checkArgument( currentPlayer.hasKey( playerKey ), "Cannot authenticate, key does not match player: ", currentPlayer );
checkArgument( currentPlayer.hasKey( playerKey ), "Cannot authenticate, key does not match player: ", currentPlayer );

currentPlayerTL.set( currentPlayer );
}

public static void authenticatedRun(final IPlayer currentPlayer, final PlayerKey playerKey, final Runnable job) {
Preconditions.checkArgument( currentPlayer.hasKey( playerKey ), "Cannot authenticate, key does not match player: ", currentPlayer );
checkArgument( currentPlayer.hasKey( playerKey ), "Cannot authenticate, key does not match player: ", currentPlayer );

playerRun( currentPlayer, job );
}
Expand All @@ -95,6 +97,15 @@ static boolean isGod() {
return !godTL.get().isEmpty() && godTL.get().peek();
}

/**
* @return true if the current player is god or can observe the target.
*
* @see IPlayer#canObserve(GameObservable)
*/
static boolean currentPlayerCanObserve(final GameObservable gameObservable) {
return isGod() || currentPlayer().canObserve( gameObservable ).isTrue();
}

@Nonnull
static IPlayer currentPlayer()
throws NotAuthenticatedException {
Expand All @@ -109,31 +120,23 @@ static IPlayer currentPlayer()
return currentPlayer;
}

public static void assertOwned(final GameObserver observer)
public static void assertOwned(final GameObservable observable)
throws NotAuthenticatedException, NotOwnedException {
if (isGod())
return;

assertSecure( observer.getOwner().isPresent() && ObjectUtils.equals( observer.getOwner().get(), currentPlayer() ), //
NotOwnedException.class, observer );
}

public static void assertObservable(final ITile location)
throws NotAuthenticatedException, NotObservableException {
if (isGod())
return;

assertSecure( currentPlayer().canObserve( location ).isTrue(), //
NotObservableException.class, location );
Maybe<? extends IPlayer> owner = observable.checkOwner();
assertSecure( owner.presence() == Maybe.Presence.PRESENT && ObjectUtils.equals( owner.get(), currentPlayer() ), //
NotOwnedException.class, observable );
}

public static void assertObservable(final IGameObject gameObject)
public static void assertObservable(final GameObservable observable)
throws NotAuthenticatedException, NotObservableException {
if (isGod())
return;

assertSecure( gameObject.checkLocation().presence() == Maybe.Presence.PRESENT, //
NotObservableException.class, gameObject );
assertSecure( currentPlayer().canObserve( observable ).isTrue(), //
NotObservableException.class, observable );
}

public static class NotAuthenticatedException extends OmicronSecurityException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,23 @@ public static <T> Maybe<T> unknown() {
return new Unknown<>();
}

/**
* @return {@link Presence#ABSENT} if reference is null, otherwise {@link Presence#PRESENT}.
*/
public static <T> Maybe<T> fromNullable(@Nullable final T reference) {
return reference == null? Maybe.<T>absent(): new Present<>( reference );
}

/**
* @return {@link Presence#ABSENT} if reference is {@link Optional#absent()}, otherwise {@link Presence#PRESENT}.
*/
public static <T> Maybe<T> fromOptional(final Optional<T> reference) {
return reference.isPresent()? new Present<>( reference.get() ): Maybe.<T>absent();
}

/**
* @return Always {@link Presence#PRESENT}.
*/
public static <T> Maybe<T> of(@Nonnull final T reference) {
return new Present<>( reference );
}
Expand Down
17 changes: 17 additions & 0 deletions omicron-api/src/main/java/com/lyndir/omicron/api/util/Maybool.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.lyndir.omicron.api.util;

import javax.annotation.Nullable;


/**
* @author lhunath, 2013-08-17
*/
Expand Down Expand Up @@ -40,4 +43,18 @@ public boolean isKnown() {
public abstract boolean isTrue();

public abstract boolean isKnown();

/**
* @return YES if value is true, NO if value is false.
*/
public static Maybool from(final boolean value) {
return value? YES: NO;
}

/**
* @return UNKNOWN if value is null, YES if value is true, NO if value is false.
*/
public static Maybool fromNullable(@Nullable final Boolean value) {
return value == null? UNKNOWN : value? YES: NO;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.lyndir.omicron.cli.command;

import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.lyndir.omicron.api.model.*;
Expand Down Expand Up @@ -70,7 +68,7 @@ public void objects(final Iterator<String> tokens) {
for (final IGameObject gameObject : gameObjectBuilder.build()) {
ITile location = gameObject.checkLocation().get();
inf( "%5s | %20s | (%7s: %3d, %3d) | %s", //
gameObject.getObjectID(), ifNotNullElse( IPlayer.class, gameObject.getOwner().orNull(), "-" ).getName(),
gameObject.getObjectID(), ifNotNullElse( IPlayer.class, gameObject.checkOwner().orNull(), "-" ).getName(),
location.getLevel().getType().getName(), location.getPosition().getX(), location.getPosition().getY(),
gameObject.getType().getTypeName() );
}
Expand Down
Loading

0 comments on commit d79c73f

Please sign in to comment.