一起做网游吧【9.5】:补丁,设置服务器地址和端口及网页管理界面更新

首先,代码还在上次的位置,我替换了压缩文件,不用再说,以后也是如此。

前几天,我准备找一个free的地图编辑器,当然,最好是open source的,同时,看看dojo,研究dojo而不是extjs是由于相比来说,dojo的模块划分我比较喜欢,而且,dojo中的测试程序都很有针对性和独立性,这个我比较喜欢。顺便将服务器的管理界面更新了下,修改成了基于dojo的。我对于extjs并没有什么恨意,只是由于不太习惯风格而已,对于extjs比较熟悉的人可能觉得extjs比较好,不管怎么,这只是一个风格而已。顺便提下学习的过程,半天时间来熟悉下小例子,半天时间将界面的布局弄好,一天时间将表格加上,用了各种办法,大概花了两天时间研究出了如何更新表格内容(可能不是正规的方法,谁要是知道的话,还请赐教)。

前段时间,我也又在落灰的wii上安装了erlang,然后将服务器仍在那个上面,运行,然后客户端在切换服务器的时候客户端挂掉!!!,原因在于服务器返回的地址是”127.0.0.1″,这是个比较严重的问题,决定将进入游戏之后的内容稍微缓和一下,反正地图编辑器还没有怎么熟悉,地图的资源也要慢慢找,就顺便的添加了下服务器的IP和端口设定,使服务器启动的时候还是监听本地的”127.0.0.1″,返还给客户端的可以是自定义的IP地址,提供端口设定是考虑到可能需要路由进行端口映射。

先说服务器内容,使用下面的函数可以获得服务器的公网IP,至于能不能公网直接访问,这就要看你的服务器的IP设定了。

       getip() ->
    case http:request(get, {"http://www.ip138.com/ip2city.asp",[]},[],[{version, 1.1}]) of 
        {ok, {{_,Ok,_},_, Content}} ->
            Index1 = string:rstr(Content, "["),
            Index2 = string:rstr(Content, "]"),
            Ip = string:sub_string(Content, Index1+1, Index2-1),
            Ip;
        Other ->
            io:format("~p~n", [Other])
    end.
       

我是从ip138.com获得的公网IP,希望不会带来什么怨言。同时,添加了一个reload函数,因为现在服务器还不是非常的问题,可能由于某些未处理的原因,造成服务器的端口监听关闭,使用下面这个函数可以重新加载。需要传递IP和Port的话,则是根据设定的ip2和port2来判定的:

 reload([]) ->
    ok;
reload([{Name, IP, Port}|Rest]) ->
    case db:search(qlc:q([ServerData || ServerData <- mnesia:table(server), 
                                        ServerData#server.name =:= Name, 
                                        ServerData#server.ip2 =:= IP,
                                        ServerData#server.port2 =:= Port,
                                        ServerData#server.enable =:=true])) of
        {atomic, []} ->
            ok;
        {atomic, Server} ->
            stopserver([{Server1#server.name, Server1#server.ip2, Server1#server.port2} || Server1 <- Server]),
            start_port(Server)
    end,
    reload(Rest);
reload([{name, Name}|Rest]) ->
    case db:search(qlc:q([ServerData || ServerData <- mnesia:table(server), 
                                        ServerData#server.name =:= Name, 
                                        ServerData#server.enable =:=true])) of
        {atomic, []} ->
            ok;
        {atomic, Server} ->
            stopserver([{Server1#server.name, Server1#server.ip2, Server1#server.port2}||Server1 <- Server]),
            start_port(Server)
    end,
    reload(Rest).      
       

关于如何设定IP和端口,则是通过setlocal来设定的:

       setlocal([]) ->
    ok;
setlocal([IP_Port|Rest]) ->
    gen_server:call(?SERVER, {setipport2, IP_Port}),
    setlocal(Rest).
       

从上面的函数中看不出什么内容,核心的方法在serverstate.erl中:

       handle_call({setipport2, {IP1, Port1}, {IP, Port}}, _From, State) ->
    Result = case db:search(qlc:q([ServerDat 
                                   || ServerDat <- mnesia:table(server), 
                                      ServerDat#server.ip =:= IP1,
                                      ServerDat#server.port =:= Port1
                                  ])) of
                 {atomic, []} ->
                     ok;
                 {atomic, [ServerDat]} ->
                     Server2 = ServerDat#server {
                                 ip2 = IP,
                                 port2 = Port
                                 },
                     ets:insert(State#state.serverstate, {Server2#server.socketpid, Server2}),
                     mnesia:transaction(fun() ->
                                                mnesia:write(Server2), Server2#server.id end),
                     ServerState = state({name, ServerDat#server.name}, State),
                     send_event(State#state.eventhandle, [{state, [ServerState]}]),
                     ok
             end,
    {reply, Result, State};
       

所做的事情其实非常的简单,查找数据库,修改数据,保存数据,修改内容中的数据。关于server:setlocal的调用方法,则是这个样子的:

       server:setlocal([
       { {"127.0.0.1", 5001},{"10.2.3.4", 3456} },
       { {"127.0.0.1", 5002},{"10.2.3.3", 3456} },
       { {"127.0.0.1", 5003},{"10.2.3.5", 3456} }
       ]).
       

说一说javascript的事情吧,服务器的状态都保存在data_full中(javascript的数组确实不错),当获得新的状态的时候,替换掉data_full中相应的值。突然想起,我忘了写stop对应的函数块了,下次添加。然后从data_full中生成新的表格数值,强制表格更新。这样处理,基本上不用做遍历比较什么的,实在是方便的佷。炫耀下代码:

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据