Fixed server compile errors, added resupply point block
|
Before Width: | Height: | Size: 176 B After Width: | Height: | Size: 176 B |
|
Before Width: | Height: | Size: 176 B |
|
After Width: | Height: | Size: 215 B |
|
Before Width: | Height: | Size: 246 B After Width: | Height: | Size: 249 B |
|
After Width: | Height: | Size: 251 B |
|
After Width: | Height: | Size: 249 B |
|
After Width: | Height: | Size: 323 B |
|
After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 109 KiB |
@@ -115,6 +115,7 @@ public class Recipes {
|
|||||||
new Recipe(liquid, LiquidBlocks.fluxpump, stack(Items.steel, 10), stack(Items.densealloy, 5)),
|
new Recipe(liquid, LiquidBlocks.fluxpump, stack(Items.steel, 10), stack(Items.densealloy, 5)),
|
||||||
|
|
||||||
new Recipe(units, UnitBlocks.repairPoint, stack(Items.steel, 10)),
|
new Recipe(units, UnitBlocks.repairPoint, stack(Items.steel, 10)),
|
||||||
|
new Recipe(units, UnitBlocks.resupplyPoint, stack(Items.steel, 10)),
|
||||||
|
|
||||||
//new Recipe(units, UnitBlocks.droneFactory, stack(Items.steel, 10)),
|
//new Recipe(units, UnitBlocks.droneFactory, stack(Items.steel, 10)),
|
||||||
//new Recipe(units, UnitBlocks.vtolFactory, stack(Items.steel, 10)),
|
//new Recipe(units, UnitBlocks.vtolFactory, stack(Items.steel, 10)),
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class PowerBlocks {
|
|||||||
}},
|
}},
|
||||||
|
|
||||||
powernode = new PowerDistributor("powernode"){{
|
powernode = new PowerDistributor("powernode"){{
|
||||||
shadow = "powernode-shadow";
|
shadow = "shadow-round-1";
|
||||||
}},
|
}},
|
||||||
|
|
||||||
powernodelarge = new PowerDistributor("powernodelarge"){{
|
powernodelarge = new PowerDistributor("powernodelarge"){{
|
||||||
|
|||||||
@@ -39,11 +39,12 @@ public class UnitBlocks {
|
|||||||
}},
|
}},
|
||||||
|
|
||||||
resupplyPoint = new ResupplyPoint("resupplypoint"){{
|
resupplyPoint = new ResupplyPoint("resupplypoint"){{
|
||||||
size = 2;
|
shadow = "shadow-round-1";
|
||||||
itemCapacity = 30;
|
itemCapacity = 30;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
repairPoint = new RepairPoint("repairpoint"){{
|
repairPoint = new RepairPoint("repairpoint"){{
|
||||||
shadow = "repairpoint-shadow";
|
shadow = "shadow-round-1";
|
||||||
|
repairSpeed = 0.1f;
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
package io.anuke.mindustry.entities.effect;
|
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
|
||||||
import io.anuke.mindustry.resource.Item;
|
|
||||||
import io.anuke.ucore.entities.Entity;
|
|
||||||
import io.anuke.ucore.graphics.Draw;
|
|
||||||
import io.anuke.ucore.util.Mathf;
|
|
||||||
|
|
||||||
public class ItemTransferEffect extends Entity {
|
|
||||||
private static final float size = 5f;
|
|
||||||
private static final float alpha = 0.1f;
|
|
||||||
|
|
||||||
private final Item item;
|
|
||||||
private final Entity target;
|
|
||||||
|
|
||||||
public ItemTransferEffect(Item item, float x, float y, Entity target) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.item = item;
|
|
||||||
this.target = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update() {
|
|
||||||
|
|
||||||
x = Mathf.lerpDelta(x, target.x, alpha);
|
|
||||||
y = Mathf.lerpDelta(y, target.y, alpha);
|
|
||||||
|
|
||||||
if(distanceTo(target) <= 2f){
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw() {
|
|
||||||
float s = size;
|
|
||||||
Draw.rect(item.region, x, y, s, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T extends Entity> T add() {
|
|
||||||
return super.add(Vars.effectGroup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -137,7 +137,7 @@ public class HudFragment implements Fragment{
|
|||||||
}}.end();
|
}}.end();
|
||||||
|
|
||||||
new table(){{
|
new table(){{
|
||||||
visible(() -> state.is(State.playing));
|
visible(() -> !state.is(State.menu));
|
||||||
atop();
|
atop();
|
||||||
aright();
|
aright();
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package io.anuke.mindustry.world.blocks.types.storage;
|
|||||||
|
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
import io.anuke.mindustry.entities.Units;
|
import io.anuke.mindustry.entities.Units;
|
||||||
import io.anuke.mindustry.entities.effect.ItemTransferEffect;
|
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
@@ -74,7 +73,7 @@ public class CoreBlock extends StorageBlock {
|
|||||||
if(tile.entity.items.items[i] > 0 && unit.acceptsAmmo(item)){
|
if(tile.entity.items.items[i] > 0 && unit.acceptsAmmo(item)){
|
||||||
tile.entity.items.items[i] --;
|
tile.entity.items.items[i] --;
|
||||||
unit.addAmmo(item);
|
unit.addAmmo(item);
|
||||||
new ItemTransferEffect(item, tile.drawx(), tile.drawy(), unit).add();
|
//new ItemTransferEffect(item, tile.drawx(), tile.drawy(), unit).add();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ public class RepairPoint extends Block{
|
|||||||
update = true;
|
update = true;
|
||||||
solid = true;
|
solid = true;
|
||||||
flags = EnumSet.of(BlockFlag.repair);
|
flags = EnumSet.of(BlockFlag.repair);
|
||||||
layer = Layer.laser;
|
layer = Layer.turret;
|
||||||
|
layer2 = Layer.laser;
|
||||||
hasItems = false;
|
hasItems = false;
|
||||||
hasPower = true;
|
hasPower = true;
|
||||||
powerCapacity = 20f;
|
powerCapacity = 20f;
|
||||||
@@ -40,15 +41,22 @@ public class RepairPoint extends Block{
|
|||||||
public void drawLayer(Tile tile) {
|
public void drawLayer(Tile tile) {
|
||||||
RepairPointEntity entity = tile.entity();
|
RepairPointEntity entity = tile.entity();
|
||||||
|
|
||||||
if(entity.target != null){
|
Draw.rect(name + "-turret", tile.drawx(), tile.drawy(), entity.rotation - 90);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawLayer2(Tile tile) {
|
||||||
|
RepairPointEntity entity = tile.entity();
|
||||||
|
|
||||||
|
if(entity.target != null &&
|
||||||
|
Angles.angleDist(entity.angleTo(entity.target), entity.rotation) < 30f){
|
||||||
float ang = entity.angleTo(entity.target);
|
float ang = entity.angleTo(entity.target);
|
||||||
float len = 2f;
|
float len = 5f;
|
||||||
|
|
||||||
Draw.color(Color.valueOf("e8ffd7"));
|
Draw.color(Color.valueOf("e8ffd7"));
|
||||||
Draw.alpha(entity.strength);
|
|
||||||
Shapes.laser("laser", "laser-end",
|
Shapes.laser("laser", "laser-end",
|
||||||
tile.drawx() + Angles.trnsx(ang, len), tile.drawy() + Angles.trnsy(ang, len),
|
tile.drawx() + Angles.trnsx(ang, len), tile.drawy() + Angles.trnsy(ang, len),
|
||||||
entity.target.x, entity.target.y);
|
entity.target.x, entity.target.y, entity.strength);
|
||||||
Draw.color();
|
Draw.color();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,15 +71,16 @@ public class RepairPoint extends Block{
|
|||||||
}else if(entity.target != null){
|
}else if(entity.target != null){
|
||||||
entity.target.health += repairSpeed * Timers.delta() * entity.strength;
|
entity.target.health += repairSpeed * Timers.delta() * entity.strength;
|
||||||
entity.target.clampHealth();
|
entity.target.clampHealth();
|
||||||
|
entity.rotation = Mathf.slerpDelta(entity.rotation, entity.angleTo(entity.target), 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float powerUse = Math.min(Timers.delta() * powerUsage, powerCapacity);
|
float powerUse = Math.min(Timers.delta() * powerUsage, powerCapacity);
|
||||||
|
|
||||||
if(entity.target != null && entity.power.amount >= powerUse){
|
if(entity.target != null && entity.power.amount >= powerUse){
|
||||||
entity.power.amount -= powerUse;
|
entity.power.amount -= powerUse;
|
||||||
entity.strength = Mathf.lerpDelta(entity.strength, 1f, 0.07f * Timers.delta());
|
entity.strength = Mathf.lerpDelta(entity.strength, 1f, 0.08f * Timers.delta());
|
||||||
}else{
|
}else{
|
||||||
entity.strength = Mathf.lerpDelta(entity.strength, 0f, 0.05f * Timers.delta());
|
entity.strength = Mathf.lerpDelta(entity.strength, 0f, 0.07f * Timers.delta());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity.timer.get(timerTarget, 20)) {
|
if(entity.timer.get(timerTarget, 20)) {
|
||||||
@@ -88,6 +97,6 @@ public class RepairPoint extends Block{
|
|||||||
|
|
||||||
public class RepairPointEntity extends TileEntity{
|
public class RepairPointEntity extends TileEntity{
|
||||||
public Unit target;
|
public Unit target;
|
||||||
public float strength;
|
public float strength, rotation = 90;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,48 +1,90 @@
|
|||||||
package io.anuke.mindustry.world.blocks.types.units;
|
package io.anuke.mindustry.world.blocks.types.units;
|
||||||
|
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
|
import io.anuke.mindustry.entities.Unit;
|
||||||
import io.anuke.mindustry.entities.Units;
|
import io.anuke.mindustry.entities.Units;
|
||||||
import io.anuke.mindustry.entities.effect.ItemTransferEffect;
|
import io.anuke.mindustry.graphics.Layer;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.flags.BlockFlag;
|
import io.anuke.mindustry.world.flags.BlockFlag;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
|
import io.anuke.ucore.graphics.Shapes;
|
||||||
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.EnumSet;
|
import io.anuke.ucore.util.EnumSet;
|
||||||
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
public class ResupplyPoint extends Block{
|
public class ResupplyPoint extends Block{
|
||||||
private static Rectangle rect = new Rectangle();
|
private static Rectangle rect = new Rectangle();
|
||||||
|
|
||||||
protected int timerSupply = timers ++;
|
protected int timerSupply = timers ++;
|
||||||
|
protected int timerTarget = timers ++;
|
||||||
|
|
||||||
protected float supplyRadius = 50f;
|
protected float supplyRadius = 50f;
|
||||||
protected float supplyInterval = 5f;
|
protected float supplyInterval = 10f;
|
||||||
|
protected float powerUsage = 0.2f;
|
||||||
|
|
||||||
public ResupplyPoint(String name) {
|
public ResupplyPoint(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
update = true;
|
update = true;
|
||||||
solid = true;
|
solid = true;
|
||||||
flags = EnumSet.of(BlockFlag.resupplyPoint);
|
flags = EnumSet.of(BlockFlag.resupplyPoint);
|
||||||
|
layer = Layer.laser;
|
||||||
|
hasItems = true;
|
||||||
|
hasPower = true;
|
||||||
|
powerCapacity = 20f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawLayer(Tile tile) {
|
||||||
|
ResupplyPointEntity entity = tile.entity();
|
||||||
|
|
||||||
|
if(entity.target != null){
|
||||||
|
float ang = entity.angleTo(entity.target);
|
||||||
|
float len = 5f;
|
||||||
|
|
||||||
|
Shapes.laser("transfer", "transfer-end",
|
||||||
|
tile.drawx() + Angles.trnsx(ang, len), tile.drawy() + Angles.trnsy(ang, len),
|
||||||
|
entity.target.x, entity.target.y, entity.strength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile) {
|
public void update(Tile tile) {
|
||||||
|
ResupplyPointEntity entity = tile.entity();
|
||||||
|
|
||||||
if(tile.entity.timer.get(timerSupply, supplyInterval)){
|
if(!validTarget(entity, entity.target) || entity.target.distanceTo(tile) > supplyRadius){
|
||||||
rect.setSize(supplyRadius*2).setCenter(tile.drawx(), tile.drawy());
|
entity.target = null;
|
||||||
|
}else if(entity.target != null && entity.strength > 0.5f){
|
||||||
Units.getNearby(tile.getTeam(), rect, unit -> {
|
|
||||||
if(unit.distanceTo(tile.drawx(), tile.drawy()) > supplyRadius) return;
|
|
||||||
|
|
||||||
|
if(entity.timer.get(timerSupply, supplyInterval)) {
|
||||||
for (int i = 0; i < tile.entity.items.items.length; i++) {
|
for (int i = 0; i < tile.entity.items.items.length; i++) {
|
||||||
Item item = Item.getByID(i);
|
Item item = Item.getByID(i);
|
||||||
if(tile.entity.items.items[i] > 0 && unit.acceptsAmmo(item)){
|
if (tile.entity.items.items[i] > 0 && entity.target.acceptsAmmo(item)) {
|
||||||
tile.entity.items.items[i]--;
|
tile.entity.items.items[i]--;
|
||||||
unit.addAmmo(item);
|
entity.target.addAmmo(item);
|
||||||
new ItemTransferEffect(item, tile.drawx(), tile.drawy(), unit).add();
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
entity.rotation = Mathf.slerpDelta(entity.rotation, entity.angleTo(entity.target), 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float powerUse = Math.min(Timers.delta() * powerUsage, powerCapacity);
|
||||||
|
|
||||||
|
if(entity.target != null && entity.power.amount >= powerUse){
|
||||||
|
entity.power.amount -= powerUse;
|
||||||
|
entity.strength = Mathf.lerpDelta(entity.strength, 1f, 0.07f * Timers.delta());
|
||||||
|
}else{
|
||||||
|
entity.strength = Mathf.lerpDelta(entity.strength, 0f, 0.05f * Timers.delta());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entity.timer.get(timerTarget, 20)) {
|
||||||
|
rect.setSize(supplyRadius * 2).setCenter(tile.drawx(), tile.drawy());
|
||||||
|
|
||||||
|
entity.target = Units.getClosest(tile.getTeam(), tile.drawx(), tile.drawy(), supplyRadius, unit -> validTarget(entity, unit));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,4 +92,27 @@ public class ResupplyPoint extends Block{
|
|||||||
public boolean acceptItem(Item item, Tile tile, Tile source) {
|
public boolean acceptItem(Item item, Tile tile, Tile source) {
|
||||||
return tile.entity.items.totalItems() < itemCapacity;
|
return tile.entity.items.totalItems() < itemCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity getEntity() {
|
||||||
|
return new ResupplyPointEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean validTarget(ResupplyPointEntity entity, Unit unit){
|
||||||
|
if(unit == null || unit.inventory.totalAmmo() >= unit.inventory.ammoCapacity()
|
||||||
|
|| unit.isDead()) return false;
|
||||||
|
|
||||||
|
for(int i = 0; i < entity.items.items.length; i ++) {
|
||||||
|
Item item = Item.getByID(i);
|
||||||
|
if (entity.items.items[i] > 0 && unit.acceptsAmmo(item)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ResupplyPointEntity extends TileEntity{
|
||||||
|
public Unit target;
|
||||||
|
public float strength, rotation = 90;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,9 +319,9 @@ public class ServerControl extends Module {
|
|||||||
if(target != null){
|
if(target != null){
|
||||||
String ip = Net.getConnection(target.clientid).address;
|
String ip = Net.getConnection(target.clientid).address;
|
||||||
netServer.admins.banPlayerIP(ip);
|
netServer.admins.banPlayerIP(ip);
|
||||||
netServer.admins.banPlayerID(netServer.admins.getTrace(ip).uuid);
|
netServer.admins.banPlayerID(target.uuid);
|
||||||
netServer.kick(target.clientid, KickReason.banned);
|
netServer.kick(target.clientid, KickReason.banned);
|
||||||
info("Banned player by IP and ID: {0} / {1}", ip, netServer.admins.getTrace(ip).uuid);
|
info("Banned player by IP and ID: {0} / {1}", ip, target.uuid);
|
||||||
}else{
|
}else{
|
||||||
info("Nobody with that name could be found.");
|
info("Nobody with that name could be found.");
|
||||||
}
|
}
|
||||||
@@ -378,7 +378,7 @@ public class ServerControl extends Module {
|
|||||||
info("Banned player by ID: {0}.", arg[0]);
|
info("Banned player by ID: {0}.", arg[0]);
|
||||||
|
|
||||||
for(Player player : playerGroup.all()){
|
for(Player player : playerGroup.all()){
|
||||||
if(netServer.admins.getTrace(Net.getConnection(player.clientid).address).uuid.equals(arg[0])){
|
if(player.uuid.equals(arg[0])){
|
||||||
netServer.kick(player.clientid, KickReason.banned);
|
netServer.kick(player.clientid, KickReason.banned);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -420,10 +420,9 @@ public class ServerControl extends Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(target != null){
|
if(target != null){
|
||||||
String id = netServer.admins.getTrace(Net.getConnection(target.clientid).address).uuid;
|
netServer.admins.adminPlayer(target.uuid, Net.getConnection(target.clientid).address);
|
||||||
netServer.admins.adminPlayer(id, Net.getConnection(target.clientid).address);
|
|
||||||
NetEvents.handleAdminSet(target, true);
|
NetEvents.handleAdminSet(target, true);
|
||||||
info("Admin-ed player by ID: {0} / {1}", id, arg[0]);
|
info("Admin-ed player by ID: {0} / {1}", target.uuid, arg[0]);
|
||||||
}else{
|
}else{
|
||||||
info("Nobody with that name could be found.");
|
info("Nobody with that name could be found.");
|
||||||
}
|
}
|
||||||
@@ -445,10 +444,9 @@ public class ServerControl extends Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(target != null){
|
if(target != null){
|
||||||
String id = netServer.admins.getTrace(Net.getConnection(target.clientid).address).uuid;
|
netServer.admins.unAdminPlayer(target.uuid);
|
||||||
netServer.admins.unAdminPlayer(id);
|
|
||||||
NetEvents.handleAdminSet(target, false);
|
NetEvents.handleAdminSet(target, false);
|
||||||
info("Un-admin-ed player by ID: {0} / {1}", id, arg[0]);
|
info("Un-admin-ed player by ID: {0} / {1}", target.uuid, arg[0]);
|
||||||
}else{
|
}else{
|
||||||
info("Nobody with that name could be found.");
|
info("Nobody with that name could be found.");
|
||||||
}
|
}
|
||||||
@@ -530,7 +528,7 @@ public class ServerControl extends Module {
|
|||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
|
||||||
for (Player player : playerGroup.all()) {
|
for (Player player : playerGroup.all()) {
|
||||||
TraceInfo info = netServer.admins.getTrace(Net.getConnection(player.clientid).address);
|
TraceInfo info = netServer.admins.getTraceByID(player.uuid);
|
||||||
if(info.totalBlocksBroken >= minbreak && info.totalBlocksBroken / Math.max(info.totalBlocksPlaced, 1f) >= ratio){
|
if(info.totalBlocksBroken >= minbreak && info.totalBlocksBroken / Math.max(info.totalBlocksPlaced, 1f) >= ratio){
|
||||||
info("&ly - Player '{0}' / UUID &lm{1}&ly found: &lc{2}&ly broken and &lc{3}&ly placed.",
|
info("&ly - Player '{0}' / UUID &lm{1}&ly found: &lc{2}&ly broken and &lc{3}&ly placed.",
|
||||||
player.name, info.uuid, info.totalBlocksBroken, info.totalBlocksPlaced);
|
player.name, info.uuid, info.totalBlocksBroken, info.totalBlocksPlaced);
|
||||||
@@ -677,7 +675,7 @@ public class ServerControl extends Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(target != null){
|
if(target != null){
|
||||||
TraceInfo info = netServer.admins.getTrace(Net.getConnection(target.clientid).address);
|
TraceInfo info = netServer.admins.getTraceByID(target.uuid);
|
||||||
Log.info("&lcTrace info for player '{0}':", target.name);
|
Log.info("&lcTrace info for player '{0}':", target.name);
|
||||||
Log.info(" &lyEntity ID: {0}", info. playerid);
|
Log.info(" &lyEntity ID: {0}", info. playerid);
|
||||||
Log.info(" &lyIP: {0}", info.ip);
|
Log.info(" &lyIP: {0}", info.ip);
|
||||||
|
|||||||