Merged with released L2J-Unity files.

This commit is contained in:
mobiusdev
2016-06-12 01:34:09 +00:00
parent e003e87887
commit 635557f5da
18352 changed files with 3245113 additions and 2892959 deletions

View File

@@ -0,0 +1,31 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.network.telnet;
import io.netty.channel.ChannelHandlerContext;
/**
* @author UnAfraid
*/
public interface ITelnetCommand
{
String getCommand();
String getUsage();
String handle(ChannelHandlerContext ctx, String[] args);
}

View File

@@ -0,0 +1,141 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.network.telnet;
import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
* @author UnAfraid
*/
public class TelnetServer
{
private static final Logger LOGGER = Logger.getLogger(TelnetServer.class.getName());
private final Map<String, ITelnetCommand> _commands = new LinkedHashMap<>();
private final EventLoopGroup _workerGroup = new NioEventLoopGroup(1);
protected TelnetServer()
{
if (Config.TELNET_ENABLED)
{
init();
}
else
{
LOGGER.info("Telnet server is currently disabled.");
}
}
public void init()
{
addHandler(new ITelnetCommand()
{
@Override
public String getCommand()
{
return "help";
}
@Override
public String getUsage()
{
return "help [command]";
}
@Override
public String handle(ChannelHandlerContext ctx, String[] args)
{
if (args.length == 0)
{
final StringBuilder sb = new StringBuilder("Available commands:" + Config.EOL);
for (ITelnetCommand cmd : TelnetServer.getInstance().getCommands())
{
sb.append(cmd.getCommand() + Config.EOL);
}
return sb.toString();
}
final ITelnetCommand cmd = TelnetServer.getInstance().getCommand(args[0]);
if (cmd == null)
{
return "Unknown command." + Config.EOL;
}
return "Usage:" + Config.EOL + cmd.getUsage() + Config.EOL;
}
});
try
{
final InetSocketAddress socket = Config.TELNET_HOSTNAME.equals("*") ? new InetSocketAddress(Config.TELNET_PORT) : new InetSocketAddress(Config.TELNET_HOSTNAME, Config.TELNET_PORT);
//@formatter:off
new ServerBootstrap().group(_workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE, true)
.childHandler(new TelnetServerInitializer())
.bind(socket);
//@formatter:on
LOGGER.info(getClass().getSimpleName() + ": Listening on " + Config.TELNET_HOSTNAME + ":" + Config.TELNET_PORT);
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, e.getMessage(), e);
}
}
public void addHandler(ITelnetCommand handler)
{
_commands.put(handler.getCommand(), handler);
}
public ITelnetCommand getCommand(String command)
{
return _commands.get(command);
}
public Collection<ITelnetCommand> getCommands()
{
return _commands.values();
}
public void shutdown()
{
_workerGroup.shutdownGracefully();
LOGGER.info("Shutting down..");
}
public static TelnetServer getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final TelnetServer _instance = new TelnetServer();
}
}

View File

@@ -0,0 +1,176 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.network.telnet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.l2jmobius.Config;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey;
/**
* @author UnAfraid
*/
@Sharable
public class TelnetServerHandler extends ChannelHandlerAdapter
{
private static final Pattern COMMAND_ARGS_PATTERN = Pattern.compile("\"([^\"]*)\"|([^\\s]+)");
private static final AttributeKey<Boolean> AUTHORIZED = AttributeKey.valueOf(TelnetServerHandler.class, "AUTHORIZED");
private String tryHandleCommand(ChannelHandlerContext ctx, String command, String[] args)
{
final ITelnetCommand cmd = TelnetServer.getInstance().getCommand(command);
if (cmd == null)
{
return "Unknown command." + Config.EOL;
}
String response = cmd.handle(ctx, args);
if (response == null)
{
response = "Usage:" + Config.EOL + cmd.getUsage() + Config.EOL;
}
return response;
}
@Override
public void channelActive(ChannelHandlerContext ctx)
{
String ip = ctx.channel().remoteAddress().toString();
ip = ip.substring(1, ip.lastIndexOf(':')); // Trim out /127.0.0.1:14013
if (!Config.TELNET_HOSTS.contains(ip))
{
final ChannelFuture future = ctx.write("Your ip: " + ip + " is not allowed to connect." + Config.EOL);
future.addListener(ChannelFutureListener.CLOSE);
ctx.flush();
return;
}
// Send greeting for a new connection.
ctx.write("Welcome to the telnet session." + Config.EOL);
ctx.write("It is " + new Date() + " now." + Config.EOL);
ctx.write("Please enter your password:" + Config.EOL);
if (!Config.TELNET_PASSWORD.isEmpty())
{
// Ask password
ctx.write("Password:");
ctx.attr(AUTHORIZED).set(Boolean.FALSE);
}
else
{
ctx.write("Type 'help' to see all available commands." + Config.EOL);
ctx.attr(AUTHORIZED).set(Boolean.TRUE);
}
ctx.flush();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
{
// Cast to a String first.
// We know it is a String because we put some codec in TelnetPipelineFactory.
String request = (String) msg;
// Generate and write a response.
String response = null;
boolean close = false;
if (Boolean.FALSE.equals(ctx.attr(AUTHORIZED).get()))
{
if (Config.TELNET_PASSWORD.equals(request))
{
ctx.attr(AUTHORIZED).set(Boolean.TRUE);
request = "";
}
else
{
response = "Wrong password!" + Config.EOL;
close = true;
}
}
if (Boolean.TRUE.equals(ctx.attr(AUTHORIZED).get()))
{
if (request.isEmpty())
{
response = "Type 'help' to see all available commands." + Config.EOL;
}
else if (request.toLowerCase().equals("exit"))
{
response = "Have a good day!" + Config.EOL;
close = true;
}
else
{
final Matcher m = COMMAND_ARGS_PATTERN.matcher(request);
if (m.find())
{
final String command = m.group();
final List<String> args = new ArrayList<>();
String arg;
while (m.find())
{
arg = m.group(1);
if (arg == null)
{
arg = m.group(0);
}
args.add(arg);
}
response = tryHandleCommand(ctx, command, args.toArray(new String[args.size()]));
if (!response.endsWith(Config.EOL))
{
response += Config.EOL;
}
}
}
}
// We do not need to write a ChannelBuffer here.
// We know the encoder inserted at TelnetPipelineFactory will do the conversion.
final ChannelFuture future = ctx.write(response);
// Close the connection after sending 'Have a good day!'
// if the client has sent 'exit'.
if (close)
{
future.addListener(ChannelFutureListener.CLOSE);
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx)
{
ctx.flush();
}
}

View File

@@ -0,0 +1,47 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.network.telnet;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
/**
* @author UnAfraid
*/
public class TelnetServerInitializer extends ChannelInitializer<SocketChannel>
{
private static final StringEncoder ENCODER = new StringEncoder();
private static final StringDecoder DECODER = new StringDecoder();
private static final TelnetServerHandler HANDLER = new TelnetServerHandler();
@Override
public void initChannel(SocketChannel ch)
{
final ChannelPipeline pipeline = ch.pipeline();
// Add the text line codec combination first,
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast(DECODER);
pipeline.addLast(ENCODER);
pipeline.addLast(HANDLER);
}
}