1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-16 14:37:39 +00:00

Compare commits

...

9 Commits

Author SHA1 Message Date
SquidDev
334ca65482 Bump to 1.93.0 2020-10-04 11:19:43 +01:00
Jonathan Coates
8472112fc1 Don't propagate adjacent redstone signals for computers (#549)
Minecraft propagates "strong" redstone signals (such as those directly
from comparators or repeaters) through solid blocks. This includes
computers, which is a little annoying as it means one cannot feed
redstone wire from one side and a repeater from another.

This changes computers to not propagate strong redstone signals, in the
same way transparent blocks like glass do.

Closes #548.
2020-10-04 11:14:22 +01:00
SquidDev
84036d97d9 Fix io.open documentation
Well, that was silly.
2020-10-02 21:21:53 +01:00
Weblate
0832974725 Translations for Swedish
Co-authored-by: David Isaksson <davidisaksson93@gmail.com>
2020-09-30 08:25:57 +00:00
SquidDev
6cee4efcd3 Fix incorrect open container check
Was this always broken, or did it happen in a Minecraft update? Don't
know, but it's a very silly mistake either way. Fixes #544
2020-09-24 17:47:30 +01:00
SquidDev
6f868849ab Use tags to check if something is a dye
We half did this already, just needed to change a couple of checks.
Closes #541.
2020-09-16 21:27:59 +01:00
SquidDev
275ca58a82 HTTP rules now allow filtering by port
The HTTP filtering system becomes even more complex! Though in this
case, it's pretty minimal, and definitely worth doing.

For instance, the following rule will allow connecting to localhost on
port :8080.

    [[http.rules]]
    host = "127.0.0.1"
    port = 8080
    action = "allow"

    # Other rules as before.

Closes #540
2020-09-15 22:05:27 +01:00
SquidDev
87393e8aef Fix additional - in docs
Why isn't this automatically stripped! Bad squid.
2020-09-13 17:56:12 +01:00
SquidDev
86bf57e3cd My inability to spell will be immortalsied in the changelog 2020-09-12 11:03:18 +01:00
19 changed files with 194 additions and 44 deletions

View File

@@ -1,5 +1,5 @@
# Mod properties
mod_version=1.92.0
mod_version=1.93.0
# Minecraft properties (update mods.toml when changing)
mc_version=1.15.2

View File

@@ -63,10 +63,10 @@ public final class ComputerCraft
public static boolean httpWebsocketEnabled = true;
public static List<AddressRule> httpRules = Collections.unmodifiableList( Stream.concat(
Stream.of( DEFAULT_HTTP_DENY )
.map( x -> AddressRule.parse( x, Action.DENY.toPartial() ) )
.map( x -> AddressRule.parse( x, null, Action.DENY.toPartial() ) )
.filter( Objects::nonNull ),
Stream.of( DEFAULT_HTTP_ALLOW )
.map( x -> AddressRule.parse( x, Action.ALLOW.toPartial() ) )
.map( x -> AddressRule.parse( x, null, Action.ALLOW.toPartial() ) )
.filter( Objects::nonNull )
).collect( Collectors.toList() ) );

View File

@@ -24,14 +24,14 @@ public class CheckUrl extends Resource<CheckUrl>
private final IAPIEnvironment environment;
private final String address;
private final String host;
private final URI uri;
public CheckUrl( ResourceGroup<CheckUrl> limiter, IAPIEnvironment environment, String address, URI uri )
{
super( limiter );
this.environment = environment;
this.address = address;
host = uri.getHost();
this.uri = uri;
}
public void run()
@@ -47,8 +47,9 @@ public class CheckUrl extends Resource<CheckUrl>
try
{
InetSocketAddress netAddress = NetworkUtils.getAddress( host, 80, false );
NetworkUtils.getOptions( host, netAddress );
boolean ssl = uri.getScheme().equalsIgnoreCase( "https" );
InetSocketAddress netAddress = NetworkUtils.getAddress( uri, ssl );
NetworkUtils.getOptions( uri.getHost(), netAddress );
if( tryClose() ) environment.queueEvent( EVENT, address, true );
}

View File

@@ -19,6 +19,7 @@ import io.netty.handler.ssl.SslContextBuilder;
import javax.net.ssl.SSLException;
import javax.net.ssl.TrustManagerFactory;
import java.net.InetSocketAddress;
import java.net.URI;
import java.security.KeyStore;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
@@ -99,6 +100,21 @@ public final class NetworkUtils
}
}
/**
* Create a {@link InetSocketAddress} from a {@link java.net.URI}.
*
* Note, this may require a DNS lookup, and so should not be executed on the main CC thread.
*
* @param uri The URI to fetch.
* @param ssl Whether to connect with SSL. This is used to find the default port if not otherwise specified.
* @return The resolved address.
* @throws HTTPRequestException If the host is not malformed.
*/
public static InetSocketAddress getAddress( URI uri, boolean ssl ) throws HTTPRequestException
{
return getAddress( uri.getHost(), uri.getPort(), ssl );
}
/**
* Create a {@link InetSocketAddress} from the resolved {@code host} and port.
*
@@ -128,7 +144,7 @@ public final class NetworkUtils
*/
public static Options getOptions( String host, InetSocketAddress address ) throws HTTPRequestException
{
Options options = AddressRule.apply( ComputerCraft.httpRules, host, address.getAddress() );
Options options = AddressRule.apply( ComputerCraft.httpRules, host, address );
if( options.action == Action.DENY ) throw new HTTPRequestException( "Domain not permitted" );
return options;
}

View File

@@ -12,6 +12,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.regex.Pattern;
/**
@@ -52,17 +53,23 @@ public final class AddressRule
private final HostRange ip;
private final Pattern domainPattern;
private final Integer port;
private final PartialOptions partial;
private AddressRule( @Nullable HostRange ip, @Nullable Pattern domainPattern, @Nonnull PartialOptions partial )
private AddressRule(
@Nullable HostRange ip,
@Nullable Pattern domainPattern,
@Nullable Integer port,
@Nonnull PartialOptions partial )
{
this.ip = ip;
this.domainPattern = domainPattern;
this.partial = partial;
this.port = port;
}
@Nullable
public static AddressRule parse( String filter, @Nonnull PartialOptions partial )
public static AddressRule parse( String filter, @Nullable Integer port, @Nonnull PartialOptions partial )
{
int cidr = filter.indexOf( '/' );
if( cidr >= 0 )
@@ -117,24 +124,27 @@ public final class AddressRule
size -= 8;
}
return new AddressRule( new HostRange( minBytes, maxBytes ), null, partial );
return new AddressRule( new HostRange( minBytes, maxBytes ), null, port, partial );
}
else
{
Pattern pattern = Pattern.compile( "^\\Q" + filter.replaceAll( "\\*", "\\\\E.*\\\\Q" ) + "\\E$" );
return new AddressRule( null, pattern, partial );
return new AddressRule( null, pattern, port, partial );
}
}
/**
* Determine whether the given address matches a series of patterns.
*
* @param domain The domain to match
* @param address The address to check.
* @param domain The domain to match
* @param socketAddress The address to check.
* @return Whether it matches any of these patterns.
*/
private boolean matches( String domain, InetAddress address )
private boolean matches( String domain, InetSocketAddress socketAddress )
{
InetAddress address = socketAddress.getAddress();
if( port != null && port != socketAddress.getPort() ) return false;
if( domainPattern != null )
{
if( domainPattern.matcher( domain ).matches() ) return true;
@@ -155,7 +165,7 @@ public final class AddressRule
return ip != null && ip.contains( address );
}
public static Options apply( Iterable<? extends AddressRule> rules, String domain, InetAddress address )
public static Options apply( Iterable<? extends AddressRule> rules, String domain, InetSocketAddress address )
{
PartialOptions options = null;
boolean hasMany = false;

View File

@@ -49,12 +49,14 @@ public class AddressRuleConfig
public static boolean checkRule( UnmodifiableConfig builder )
{
String hostObj = get( builder, "host", String.class ).orElse( null );
Integer port = get( builder, "port", Number.class ).map( Number::intValue ).orElse( null );
return hostObj != null && checkEnum( builder, "action", Action.class )
&& check( builder, "port", Number.class )
&& check( builder, "timeout", Number.class )
&& check( builder, "max_upload", Number.class )
&& check( builder, "max_download", Number.class )
&& check( builder, "websocket_message", Number.class )
&& AddressRule.parse( hostObj, PartialOptions.DEFAULT ) != null;
&& AddressRule.parse( hostObj, port, PartialOptions.DEFAULT ) != null;
}
@Nullable
@@ -64,6 +66,7 @@ public class AddressRuleConfig
if( hostObj == null ) return null;
Action action = getEnum( builder, "action", Action.class ).orElse( null );
Integer port = get( builder, "port", Number.class ).map( Number::intValue ).orElse( null );
Integer timeout = get( builder, "timeout", Number.class ).map( Number::intValue ).orElse( null );
Long maxUpload = get( builder, "max_upload", Number.class ).map( Number::longValue ).orElse( null );
Long maxDownload = get( builder, "max_download", Number.class ).map( Number::longValue ).orElse( null );
@@ -77,7 +80,7 @@ public class AddressRuleConfig
websocketMessage
);
return AddressRule.parse( hostObj, options );
return AddressRule.parse( hostObj, port, options );
}
private static <T> boolean check( UnmodifiableConfig config, String field, Class<T> klass )

View File

@@ -136,7 +136,7 @@ public class HttpRequest extends Resource<HttpRequest>
try
{
boolean ssl = uri.getScheme().equalsIgnoreCase( "https" );
InetSocketAddress socketAddress = NetworkUtils.getAddress( uri.getHost(), uri.getPort(), ssl );
InetSocketAddress socketAddress = NetworkUtils.getAddress( uri, ssl );
Options options = NetworkUtils.getOptions( uri.getHost(), socketAddress );
SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null;

View File

@@ -129,8 +129,7 @@ public class Websocket extends Resource<Websocket>
try
{
boolean ssl = uri.getScheme().equalsIgnoreCase( "wss" );
InetSocketAddress socketAddress = NetworkUtils.getAddress( uri.getHost(), uri.getPort(), ssl );
InetSocketAddress socketAddress = NetworkUtils.getAddress( uri, ssl );
Options options = NetworkUtils.getOptions( uri.getHost(), socketAddress );
SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null;

View File

@@ -24,6 +24,7 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.storage.loot.LootContext;
@@ -180,4 +181,10 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
if( label != null ) computer.setLabel( label );
}
}
@Override
public boolean shouldCheckWeakPower( BlockState state, IWorldReader world, BlockPos pos, Direction side )
{
return false;
}
}

View File

@@ -13,7 +13,6 @@ import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.DyeItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIntArray;
import net.minecraft.util.IntArray;
@@ -95,7 +94,7 @@ public class ContainerPrinter extends Container
else
{
// Transfer from inventory to printer
if( stack.getItem() instanceof DyeItem )
if( TilePrinter.isInk( stack ) )
{
if( !mergeItemStack( stack, 0, 1, false ) ) return ItemStack.EMPTY;
}

View File

@@ -300,9 +300,9 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
}
}
private static boolean isInk( @Nonnull ItemStack stack )
static boolean isInk( @Nonnull ItemStack stack )
{
return stack.getItem() instanceof DyeItem;
return ColourUtils.getStackColour( stack ) != null;
}
private static boolean isPaper( @Nonnull ItemStack stack )
@@ -321,7 +321,8 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
private boolean inputPage()
{
ItemStack inkStack = m_inventory.get( 0 );
if( !isInk( inkStack ) ) return false;
DyeColor dye = ColourUtils.getStackColour( inkStack );
if( dye == null ) return false;
for( int i = 1; i < 7; i++ )
{
@@ -329,8 +330,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
if( paperStack.isEmpty() || !isPaper( paperStack ) ) continue;
// Setup the new page
DyeColor dye = ColourUtils.getStackColour( inkStack );
m_page.setTextColour( dye != null ? dye.getId() : 15 );
m_page.setTextColour( dye.getId() );
m_page.clear();
if( paperStack.getItem() instanceof ItemPrintout )

View File

@@ -55,11 +55,10 @@ public final class TurtlePlayer extends FakePlayer
private void setState( ITurtleAccess turtle )
{
if( openContainer != null )
if( openContainer != container )
{
ComputerCraft.log.warn( "Turtle has open container ({})", openContainer );
openContainer.onContainerClosed( this );
openContainer = null;
closeContainer();
}
BlockPos position = turtle.getPosition();

View File

@@ -40,6 +40,8 @@ public final class ColourUtils
public static DyeColor getStackColour( ItemStack stack )
{
if( stack.isEmpty() ) return null;
for( int i = 0; i < DYES.length; i++ )
{
Tag<Item> dye = DYES[i];

View File

@@ -1,14 +1,14 @@
{
"block.computercraft.computer_normal": "Dator",
"block.computercraft.computer_advanced": "Avancerad Dator",
"block.computercraft.computer_command": "Kommando Dator",
"block.computercraft.computer_command": "Kommandodator",
"block.computercraft.disk_drive": "Diskettläsare",
"block.computercraft.printer": "Skrivare",
"block.computercraft.speaker": "Högtalare",
"block.computercraft.monitor_normal": "Skärm",
"block.computercraft.monitor_advanced": "Avancerad Skärm",
"block.computercraft.wireless_modem_normal": "Trådlöst Modem",
"block.computercraft.wireless_modem_advanced": "Ender Modem",
"block.computercraft.wireless_modem_advanced": "Endermodem",
"block.computercraft.wired_modem": "Trådat Modem",
"block.computercraft.cable": "Nätverkskabel",
"block.computercraft.wired_modem_full": "Trådat Modem",
@@ -38,5 +38,76 @@
"upgrade.computercraft.speaker.adjective": "Högljudd",
"chat.computercraft.wired_modem.peripheral_connected": "Kringutrustning \"%s\" är kopplad till nätverket",
"chat.computercraft.wired_modem.peripheral_disconnected": "Kringutrustning \"%s\" är frånkopplad från nätverket",
"gui.computercraft.tooltip.copy": "Kopiera till urklipp"
"gui.computercraft.tooltip.copy": "Kopiera till urklipp",
"gui.computercraft.tooltip.disk_id": "Diskett-ID: %s",
"gui.computercraft.tooltip.computer_id": "Dator-ID: %s",
"tracking_field.computercraft.coroutines_dead.name": "Coroutines borttagna",
"tracking_field.computercraft.coroutines_created.name": "Coroutines skapade",
"tracking_field.computercraft.websocket_outgoing.name": "Websocket utgående",
"tracking_field.computercraft.websocket_incoming.name": "Websocket ingående",
"tracking_field.computercraft.http_download.name": "HTTP-nedladdning",
"tracking_field.computercraft.http_upload.name": "HTTP-uppladdning",
"tracking_field.computercraft.http.name": "HTTP-förfrågningar",
"tracking_field.computercraft.turtle.name": "Turtle-operationer",
"tracking_field.computercraft.fs.name": "Filsystemoperationer",
"tracking_field.computercraft.peripheral.name": "Samtal till kringutrustning",
"tracking_field.computercraft.server_time.name": "Serveraktivitetstid",
"tracking_field.computercraft.server_count.name": "Antal serveruppgifter",
"tracking_field.computercraft.max.name": "Max tid",
"tracking_field.computercraft.average.name": "Genomsnittlig tid",
"tracking_field.computercraft.total.name": "Total tid",
"tracking_field.computercraft.tasks.name": "Uppgifter",
"argument.computercraft.argument_expected": "Argument förväntas",
"argument.computercraft.tracking_field.no_field": "Okänt fält '%s'",
"argument.computercraft.computer.many_matching": "Flera datorer matchar '%s' (%s träffar)",
"argument.computercraft.computer.no_matching": "Inga datorer matchar '%s'",
"commands.computercraft.generic.additional_rows": "%d ytterligare rader…",
"commands.computercraft.generic.exception": "Ohanterat felfall (%s)",
"commands.computercraft.generic.no": "N",
"commands.computercraft.generic.yes": "J",
"commands.computercraft.generic.position": "%s, %s, %s",
"commands.computercraft.generic.no_position": "<no pos>",
"commands.computercraft.queue.desc": "Skicka ett computer_command event till en kommandodator, skicka vidare ytterligare argument. Detta är mestadels utformat för kartmarkörer som fungerar som en mer datorvänlig version av /trigger. Alla spelare kan köra kommandot, vilket sannolikt skulle göras genom en textkomponents klick-event.",
"commands.computercraft.queue.synopsis": "Skicka ett computer_command event till en kommandodator",
"commands.computercraft.reload.done": "Konfiguration omladdad",
"commands.computercraft.reload.desc": "Ladda om ComputerCrafts konfigurationsfil",
"commands.computercraft.reload.synopsis": "Ladda om ComputerCrafts konfigurationsfil",
"commands.computercraft.track.dump.computer": "Dator",
"commands.computercraft.track.dump.no_timings": "Inga tidtagningar tillgängliga",
"commands.computercraft.track.dump.desc": "Dumpa de senaste resultaten av datorspårning.",
"commands.computercraft.track.dump.synopsis": "Dumpa de senaste spårningsresultaten",
"commands.computercraft.track.stop.not_enabled": "Spårar för tillfället inga datorer",
"commands.computercraft.track.stop.action": "Klicka för att stoppa spårning",
"commands.computercraft.track.stop.desc": "Stoppa spårning av alla datorers körtider och eventräkningar",
"commands.computercraft.track.stop.synopsis": "Stoppa spårning för alla datorer",
"commands.computercraft.track.start.stop": "Kör %s för att stoppa spårning och visa resultaten",
"commands.computercraft.track.start.desc": "Börja spåra alla dators körtider och eventräkningar. Detta kommer återställa resultaten från tidigare körningar.",
"commands.computercraft.track.start.synopsis": "Starta spårning för alla datorer",
"commands.computercraft.track.desc": "Spåra hur länge datorer exekverar, och även hur många event de hanterar. Detta presenterar information på liknande sätt som /forge track och kan vara användbart för att undersöka lagg.",
"commands.computercraft.track.synopsis": "Spåra körningstider för denna dator.",
"commands.computercraft.view.not_player": "Kan inte öppna terminalen för en ickespelare",
"commands.computercraft.view.action": "Titta på denna dator",
"commands.computercraft.view.desc": "Öppna datorns terminal för att möjligöra fjärrstyrning. Detta ger inte tillgång till turtlens inventory. Du kan ange en dators instans-id (t.ex. 123) eller dator-id (t.ex. #123).",
"commands.computercraft.view.synopsis": "Titta på datorns terminal.",
"commands.computercraft.tp.not_there": "Kan inte hitta datorn i världen",
"commands.computercraft.tp.not_player": "Kan inte öppna terminalen för en ickespelare",
"commands.computercraft.tp.action": "Teleportera till den här datorn",
"commands.computercraft.tp.desc": "Teleportera till datorns position. Du kan ange en dators instans-id (t.ex. 123), dator-id (t.ex. #123) eller etikett (t.ex. \"@Min dator\").",
"commands.computercraft.tp.synopsis": "Teleportera till en specifik dator.",
"commands.computercraft.turn_on.done": "Startade %s/%s datorer",
"commands.computercraft.turn_on.desc": "Starta de listade datorerna eller alla om ingen anges. Du kan ange en dators instans-id (t.ex. 123), dator-id (t.ex. #123) eller etikett (t.ex. \"@Min dator\").",
"commands.computercraft.turn_on.synopsis": "Starta på datorer på distans.",
"commands.computercraft.shutdown.done": "Stängde av %s/%s datorer",
"commands.computercraft.dump.desc": "Visa status för alla datorer eller specifik information för en dator. Du kan ange en dators instans-id (t.ex. 123), dator-id (t.ex. #123) eller etikett (t.ex. \"@Min dator\").",
"commands.computercraft.shutdown.desc": "Stäng av de listade datorerna eller alla om ingen anges. Du kan ange en dators instans-id (t.ex. 123), dator-id (t.ex. #123) eller etikett (t.ex. \"@Min dator\").",
"commands.computercraft.shutdown.synopsis": "Stäng av datorer på distans.",
"commands.computercraft.dump.action": "Visa mer information om den här datorn",
"commands.computercraft.dump.synopsis": "Visa status för datorer.",
"commands.computercraft.help.no_command": "Inget sådant kommando '%s'",
"commands.computercraft.help.no_children": "%s har inget underkommando",
"commands.computercraft.help.desc": "Visa detta hjälpmeddelande",
"commands.computercraft.help.synopsis": "Tillhandahåll hjälp för ett specifikt kommando",
"commands.computercraft.desc": "/computercraft kommandot tillhandahåller olika debugging- och administrationsverktyg för att kontrollera och interagera med datorer.",
"commands.computercraft.synopsis": "Olika kommandon för att kontrollera datorer.",
"itemGroup.computercraft": "ComputerCraft"
}

View File

@@ -289,7 +289,7 @@ end
-- The `mode` string can be any of the following:
-- - **"r"**: Read mode
-- - **"w"**: Write mode
-- - **"w"**: Append mode
-- - **"a"**: Append mode
--
-- The mode may also have a `b` at the end, which opens the file in "binary
-- mode". This allows you to read binary files, as well as seek within a file.

View File

@@ -440,7 +440,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
end
--- Get the buffered contents of a line in this window.
---
--
-- @tparam number y The y position of the line to get.
-- @treturn string The textual content of this line.
-- @treturn string The text colours of this line, suitable for use with @{term.blit}.

View File

@@ -1,3 +1,13 @@
# New features in CC: Tweaked 1.93.0
* Update Swedish translations (Granddave).
* Printers use item tags to check dyes.
* HTTP rules may now be targetted for a specific port.
* Don't propagate adjacent redstone signals through computers.
And several bug fixes:
* Fix NPEs when turtles interact with containers.
# New features in CC: Tweaked 1.92.0
* Bump Cobalt version:
@@ -7,7 +17,7 @@
And several bug fixes:
* Correctly handle tabs within textutils.unserailizeJSON.
* Fix sheep not dropping items when sheered by turtles.
* Fix sheep not dropping items when sheared by turtles.
# New features in CC: Tweaked 1.91.0

View File

@@ -1,12 +1,11 @@
New features in CC: Tweaked 1.92.0
New features in CC: Tweaked 1.93.0
* Bump Cobalt version:
* Add support for the __pairs metamethod.
* string.format now uses the __tostring metamethod.
* Add date-specific MOTDs (MCJack123).
* Update Swedish translations (Granddave).
* Printers use item tags to check dyes.
* HTTP rules may now be targetted for a specific port.
* Don't propagate adjacent redstone signals through computers.
And several bug fixes:
* Correctly handle tabs within textutils.unserailizeJSON.
* Fix sheep not dropping items when sheered by turtles.
* Fix NPEs when turtles interact with containers.
Type "help changelog" to see the full version history.

View File

@@ -0,0 +1,34 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.core.apis.http.options;
import org.junit.jupiter.api.Test;
import java.net.InetSocketAddress;
import java.util.Collections;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class AddressRuleTest
{
@Test
public void matchesPort()
{
Iterable<AddressRule> rules = Collections.singletonList( AddressRule.parse(
"127.0.0.1", 8080,
new PartialOptions( Action.ALLOW, null, null, null, null )
) );
assertEquals( apply( rules, "localhost", 8080 ).action, Action.ALLOW );
assertEquals( apply( rules, "localhost", 8081 ).action, Action.DENY );
}
private Options apply( Iterable<AddressRule> rules, String host, int port )
{
return AddressRule.apply( rules, host, new InetSocketAddress( host, port ) );
}
}