目录
简单的MUD服务器
main.rb
#!/usr/bin/ruby
#encoding:UTF-8
require 'eventmachine'
require_relative 'MudGameServer'
require_relative 'GmCmd'
require 'time'
VERSION =0.01
EventMachine.run {
$client_count=0
$action={}
puts "waterRbMud server V#{VERSION} start..."
host, port,mg_port = get_server_ip_info()
puts "[a mud server written with ruby.]"
EventMachine.start_server host, port, MudGameServer
EventMachine.start_server(host, mg_port, GmCmd)
puts DateTime.now
puts "waterRbMud server was running."
puts "接受player连接: #{host}: #{port}..."
puts "接受GM连接: #{host}: #{mg_port}..."
}
MudGameServer
#encoding:UTF-8
#!/usr/bin/ruby
require 'json'
def get_server_ip_info
main_port=2023
manager_port=9999
ip_info=`ifconfig -a`
ip_info=~/inet\s+(?!127\.0\.0\.1)([0-9\.]+)/
[$1,main_port,manager_port]
end
module MudGameServer
def post_init
init_game_data
puts "第#{$client_count}个客户端已经连接到服务器![#{DateTime.now}]"
send_data "login 用户名 密码:\n"
send_data "#"
end
def receive_data data
if !data || data.chomp.strip==""
send_data "#"
return
end
data_utf8=data.strip.force_encoding('utf-8')
begin
@received_data=data_utf8.split(/\s+/)
client_cmd=@received_data[0]
player_cmd(client_cmd)
rescue ArgumentError=>e
@@game_client.delete(@user)
close_connection
end
end
def unbind
$client_count-=1
puts "1个客户端退出,还有#{$client_count}个客户端连接中![#{DateTime.now}]"
if $client_count==0
puts "当前无客户端连接!"
end
end
def init_game_data
@@game_client={}
@scene_act={}
@current_room_id=0
@current_order_id=0
$client_count+=1
@now_story_id="0-0"
$action["think"]="想:"
$action["talk_to_myself"]="自言自语:"
$action["plot"]=":"
#now_story_id
File.open("gameData_#{@now_story_id}.json", "r") do |json_file|
@json_obj = JSON.parse json_file.read
end
end
def player_cmd(cmd_str)
p_cmd=cmd_str.downcase
if p_cmd=="now"
send_data ">>>#{@user},#{DateTime.now}\n#"
elsif p_cmd=="login"
@user,@passwd=@received_data[1..2]
@@game_client[@user]=self
send_data ">>>#{@user},欢迎您光临\n#"
out_str=get_scene_output(@current_room_id,@current_order_id)
if out_str
send_data "\n#{out_str}"
end
elsif p_cmd=="quit"
@@game_client.delete(@user)
close_connection
elsif p_cmd=="talkto"
user,message=@received_data[1..2]
send_data "#"
if @@game_client.has_key?(user)
@@game_client[user].send_data ">>>#{@user}对#{user}说:\n#{message}\n#"
end
elsif @scene_act.has_key?(p_cmd)
case @scene_act[p_cmd].split[0]
when "next"
@current_order_id+=1
@scene_act.clear
when "go_order_id"
@current_order_id=@scene_act[p_cmd].split[1].to_i
@scene_act.clear
end
out_str=get_scene_output(@current_room_id,@current_order_id)
if out_str
send_data out_str
else
@current_order_id-=1
send_data ">>>#{@user},无效指令:#{cmd_str}\n#"
end
else
*params=@received_data[1..-1]
send_data ">>>#{@user},无效指令:#{cmd_str},无效参数:#{params.join(" ")}\n#"
end
end
def get_scene_output(c_room_id,c_order_id)
now_scene_data=get_game_scene(c_room_id,c_order_id)
if now_scene_data
sel_str=""
@scene_act={}
now_scene_data[:action_sel].each do |sel,act|
sel_kb=sel.split('-|')[0]
sel_str+=sel+"\n"
@scene_act[sel_kb]=act.strip
end
out_str=">>>#{@user}现在在#{now_scene_data[:room_name]}\n"
out_str+="#{@user}#{now_scene_data[:action_name]}\n"
out_str+="#{now_scene_data[:action_data].join("\n")}\n"
out_str.gsub!('#player_user#',@user)
out_str+=sel_str+"\n#"
return out_str
else
return nil
end
end
def get_game_scene(room_id,order_id)
room_name=""
action_type=""
action_name=""
action_data=""
action_sel={}
sub_scene=@json_obj["data"]
sub_scene.each do |player_info|
if player_info["id"].to_i==room_id
room_name=player_info["name"]
player_info["data"].each do |player_data|
if player_data["order_id"].to_i==order_id
action_type=player_data["type"].strip
action_name=$action[action_type]
action_data= player_data["data"]
action_sel= player_data["select"]
return {"room_name":room_name,"action_type":action_type,"action_name":action_name,"action_data":action_data,"action_sel":action_sel}
end
end
end
end
return nil
end
end
test.rb
require 'eventmachine'
module MudGameServer
@@client_count=0
def post_init
@@client_count+=1
puts "第#{@@client_count}个客户端已经连接到服务器!"
end
def receive_data data
mud_data=data.gsub(" ","").force_encoding('utf-8')
send_data "#你发送的消息: #{mud_data}"
close_connection if data =~ /quit/i
end
def unbind
@@client_count-=1
puts "1个客户端退出,还有#{@@client_count}个客户端连接中!"
if @client_count==0
puts "当前无客户端连接!"
end
end
def query_client_count
puts "当前#{@@client_count}个客户端连接!"
end
end
# Note that this will block current thread.
EventMachine.run {
EventMachine.start_server "127.0.0.1", 8081, MudGameServer
}
GmCmd.rb
#encoding:UTF-8
require_relative 'EncryStr'
module GmCmd
@@gm_count=0
@@gm_passwd=['a29b0@*^','z-=?2#\;','~#3-sr|l']
def post_init
init_gm_command
@@gm_count+=1
puts "第#{@@gm_count}个gm客户端已经连接到服务器!"
end
def receive_data data
if !data || data.chomp.strip==""
send_data ">>>"
else
data=data.chomp
begin
data=decry_str(data,@@gm_passwd)
@received_data=data.strip.force_encoding('utf-8').split(/\s+/)
client_cmd=@received_data[0]
game_master_cmd(client_cmd)
rescue ArgumentError=>e
close_connection
end
end
end
def unbind
@@gm_count-=1
puts "1个gm客户端退出,还有#{@@gm_count}个gm客户端连接中![#{DateTime.now}]"
if @@gm_count==0
puts "当前无gm客户端连接!"
end
end
def init_gm_command
@@gm_command={}
@@gm_command["version"]=Proc.new do
send_data ">>>#{VERSION}\n###"
end
@@gm_command["gmlogin"]=Proc.new do
@user,@passwd=@received_data[1..2]
puts "gm客户端#{@user}已经登录[#{DateTime.now}]"
send_data ">>>#{@user},欢迎您光临\n###"
end
@@gm_command["ccount"] =Proc.new do
send_data ">>>当前#{$client_count}个客户端连接![#{DateTime.now}]\n###"
end
@@gm_command["gcount"] =Proc.new do
send_data ">>>当前#{@@gm_count}个gm客户端连接![#{DateTime.now}]\n###"
end
@@gm_command["now"]=Proc.new do
send_data ">>>#{@user},#{DateTime.now}\n###"
end
@@gm_command["quit"]=Proc.new do
close_connection
end
end
def game_master_cmd(cmd_str)
gm_cmd=cmd_str.downcase
if @@gm_command.has_key?(gm_cmd)
@@gm_command[gm_cmd].call()
else
*params=@received_data[1..-1]
send_data ">>>#{@user},无效指令:#{gm_cmd},无效参数:#{params.join(" ")}\n###s"
end
end
end
gmclient.rb
#!/usr/bin/ruby
#encoding:UTF-8
require 'eventmachine'
require_relative 'EncryStr'
$gm_port=9999
$gm_server='192.168.1.105'
$gm_passwd=['a29b0@*^','z-=?2#\;','~#3-sr|l']
$user="gm"
$passwd="124321"
module GmCmdClient
def post_init
puts "开始连接服务器[#{$gm_server}:#{$gm_port}]...."
login_data=encry_str("gmlogin #{$user} #{$passwd}",$gm_passwd)
send_data login_data
end
def receive_data data
print data
input_data=""
loop do
begin
input_data=gets.chomp.strip
if input_data!=""
break
else
print "###"
end
rescue Exception=>e
puts "error!"
p e
print "###"
end
end
input_data=encry_str(input_data,$gm_passwd)
send_data input_data
end
def unbind
EventMachine::stop_event_loop
end
end
EventMachine.run do
EventMachine.connect $gm_server, $gm_port, GmCmdClient
end
EncryStr.rb
#!/usr/bin/ruby
#encoding:UTF-8
require 'des'
def encry_str(data,passwd)
des_encry(des_decry(des_encry(data,passwd[0]),passwd[1]),passwd[2])
end
def decry_str(data,passwd)
des_decry(des_encry(des_decry(data,passwd[2]),passwd[1]),passwd[0])
end
def des_encry(data,passwd)
ec_data=""
pad_data=""
data_length=data.length
for i in (0...data.length).step 8
s_data=data[i,8]
if data_length < 8
for i in 0...8-data_length
pad_data+=" "
end
s_data+=pad_data
end
ec_data+=DES.encrypt(s_data, passwd).to_s
data_length-=8
end
return ec_data
end
def des_decry(data,passwd)
dc_data=""
for i in (0...data.length).step 8
s_data=data[i,8]
dc_data+=DES.decrypt(DES::Block.new(s_data), passwd).to_s
end
dc_data.slice!(/\*+$/)
return dc_data
end
def test
passwd=["aqsw1234",'a-=?2##;','~#0-sr|l']
s1=encry_str("gmlogin sss 325 ",passwd)
s2=decry_str(s1,passwd)
puts s1
puts s2
end
#test
gameData_0-0.json
{
"id":"0-0",
"type":"scene",
"data":
[
{"id":0 ,
"type":"room",
"name":"自己家里",
"data":
[
{
"order_id":0,
"type":"think",
"data": [
"我这是在哪呢?\n原来是在自己家里,又是平静的一个周日。",
"快盛夏了,昨天天气预报,今天气温38度,天气就这么热了。",
"现在几点了?\n还只有9点。"
],
"select":{"1-|继续":"next"}
},
{
"order_id":1,
"type":"talk_to_myself",
"data": ["再睡会觉,时间还早呢!",
"外面怎么这么吵!又是那些跳广场舞的大妈。",
"唉!还让不让我睡觉了!"],
"select":{"1-|继续":"next"}
},
{
"order_id":2,
"type":"plot",
"data": [
"我拉开窗帘,外面的阳光比以前更加耀眼,天上好像有两个太阳,这咋回事?",
"跳广场舞的音乐继续放着,可是外面那些的大妈也没有在跳广场舞,都在指着天上的太阳,好像在议论着什么。"],
"select":{"1-|继续":"next"}
},
{
"order_id":3,
"type":"think",
"data": [
"这咋回事,可能真的两太阳?",
"这个天文自然现象百年不遇,不管它了,实在太困了。",
"对,先睡觉,起床后,再看看怎么回事!"],
"select":{"1-|继续":"next"}
},
{
"order_id":4,
"type":"plot",
"data": [
"我拉上窗帘,睡了不知道多久,被外面的敲门声吵醒",
"这谁呀?一般没有人周日这时候来到我家找我?",
"我大学毕业后,就来这个城市打工也有好几年了,这个曾经陌生的城市,现在已经很熟悉了。",
"现在我一个住在这租来的房子里,小区位置偏远了一些,但环境不错,租金也不贵。"
],
"select":{"1-|继续":"next"}
},
{
"order_id":5,
"type":"think",
"data":
["同事一般来我家玩,都要和我预约时间,这谁呢?!",
"这么早来打扰我的美梦。敲门声还在继续,而且越敲越重。",
"要不要打开门看看呢?"],
"select":{"1-|不开门":"next","2-|开门":"go_order_id 7"}
},
{
"order_id":6,
"type":"plot",
"data":
["一个厚重的男声说:‘开门,我们有要事找您,您不开门会后悔一辈子的。’",
"一个清脆的女声说:‘先生,我们是好人,请您打开门。这样吧,我们把信放在门口,请您一定要看。’"
],
"select":{"1-|开门":"next"}
},
{
"order_id":7,
"type":"plot",
"data":
["我迟疑了许久,才打开门。",
"门外已经没有人了,那些敲门的人肯定离开了。",
"我捡起门口的信封,回到家里。"
],
"select":{"1-|阅信":"next"}
},
{
"order_id":8,
"type":"plot",
"data":
["我打开信封,里面有一张卡片,上面写着:",
"尊敬的#player_user#,请您于今天下午4点,到本市的白蛋酒店集合,晚上参加会餐",
"会议重要,请勿缺席,会后您将参加一个长期旅行团,请您携带可以长期生活的一切必要行李",
"此次旅行将很漫长,请做好充足的准备,感谢您的参加",
"卡片下面画了一个红色的小球,外面包围着很多银色的小球。"
],
"select":{"1-|继续":"next"}
},
{
"order_id":9,
"type":"think",
"data":
["这是个什么样的会议,很奇怪?!",
"卡片下面绘制的图案很精美,只是不知道代表了什么特殊的含义。",
"参加会议免费,还可以有晚餐,还可以免费旅行。",
"只是不知道这次旅行好玩不,去哪此地方玩",
"还要带上长期生活的行李,如果参加会议,肯定暂时回来不了,去不去呢?",
"反正吃喝玩乐免费,万一有危险,我离开酒店就可以了,这个酒店我去过,是一个大型正规酒店。",
"还是去吧!就这么决定了,现在就开始清理行李,随便做个中饭就出发",
"走之前,我还得把房间处理好,暂时回不来了,把水电和天然气都关好。"
],
"select":{"1-|吃完中饭":"next"}
}
]
}
]
}
标签:实战,end,ruby,cmd,手册,str,gm,data,id
From: https://www.cnblogs.com/waterruby/p/17688221.html