Commits

Yuriy Netesov committed 717a976 Draft

work on protocol

Comments (0)

Files changed (6)

apps/kissbang/src/proxy_srv.erl

                         [] ->
                             unknown_origin;
                         [UserOrigin] ->
-%                            mnesia:delete({user_origin, UserOrigin#user_origin.guid}),
+                            mnesia:delete({user_origin, UserOrigin#user_origin.guid}),
                             {ok, UserOrigin#user_origin.origin}
                         end
             end,

common/protocol/kissbang.xml

+<protocol name="kissbang">
+  <!-- authorization -->
+  <message name="authorize">
+    <field name="name" type="string"/>
+    <field name="password" type="string"/>
+  </message>
+
+  <message name="authorized">
+  </message>
+
+  <message name="authorization_failed">
+    <file name="reason" type="string"/>
+  </message>
+
+  <!-- chat -->
+  <message name="send_chat_message_to_room">
+    <field name="message" type="string"/>
+  </message>
+
+  <message name="on_got_chat_message">
+    <field name="sender_guid" type="string"/>
+    <field name="message" type="string"/>
+  </message>
+
+  <!-- mail -->
+  <message name="sent_mail">
+    <field name="receiver_guid" type="string"/>
+    <field name="title" type="string"/>
+    <field name="body" type="string"/>
+  </message>
+
+  <message name="check_mailbox">
+  </message>
+
+  <message name="on_got_mailbox">
+    
+  </message>
+
+  <message name="read_mail">
+    
+  </message>
+
+  <!-- rooms -->
+  <message name="find_random_room">
+  </message>
+
+  <message name="on_we_joined_room">
+    <field name="room_guid" type="string"/>
+  </message>
+
+  <message name="on_room_starts">
+  </message>
+
+  <!-- bottle game -->
+  <message name="prepare_to_swing_bottle">
+  </message>
+
+  <message name="swing_bottle">
+  </message>
+
+  <message name="on_bottle_choice">
+    <field name="chosen_guid" type="string"/>
+  </message>
+
+  <message name="kiss"/>
+
+  <message name="on_kissed"/>
+
+  <message name="refuse_to_kiss"/>
+
+  <message name="on_kiss_refused"/>
+    
+</protocol>

common/protocol/tools/generators/erlang.xslt

+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="text"/>
+
+<xsl:template match="field">
+  <xsl:value-of select="@name"/>
+</xsl:template>
+
+<xsl:template match="message">
+  	-record(<xsl:value-of select="@name"/>, {
+	<xsl:for-each select="field">
+	  <xsl:apply-templates select="."/>
+	  <xsl:if test="position() != last()">
+                <xsl:text>,  </xsl:text>
+      </xsl:if>
+	</xsl:for-each>
+	}).
+</xsl:template>
+
+<xsl:template match="/protocol">
+  <xsl:apply-templates select="message"/>
+</xsl:template>
+
+
+</xsl:stylesheet>

common/protocol/tools/generators/erlang_router.xslt

+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="text"/>
+
+<xsl:template match="message[destination != 'client']">
+   route_message(UserId, Message=#<xsl:value-of select="@name"/>{}, Callback) <xsl:text disable-output-escaping="yes">-></xsl:text>
+       vs_logger:debug("[vs_proxy] routing message <xsl:value-of select="destination"/>"),
+       <xsl:value-of select="destination"/>:handle_message(UserId, Message, Callback);
+</xsl:template>
+
+<xsl:template match="message">
+</xsl:template>
+
+<xsl:template match="/protocol">
+  -module(<xsl:value-of select="@name"/>_router).
+  -include("<xsl:value-of select="@name"/>.hrl").
+  -export([route_message/3]).
+  <xsl:apply-templates select="message"/>
+  <xsl:text disable-output-escaping="yes">
+  route_message(_UserId, UnknownMessage, _Callback) ->	
+  	   {unknown_message, UnknownMessage}.
+  </xsl:text>
+</xsl:template>
+
+
+</xsl:stylesheet>

common/protocol/tools/generators/erlang_serialize.xslt

+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="text"/>
+
+<!-- serialize templates -->
+
+  <xsl:template match="field[@type='list' and @of='int']" mode="serialize">
+	++ serialize_field(Message#<xsl:value-of select="../@name"/>.<xsl:value-of select="@name"/>, 
+	list_int, <xsl:value-of select="@name"/>)
+  </xsl:template>
+
+  <xsl:template match="field[@type='list' and @of='float']" mode="serialize">
+	++ serialize_field(Message#<xsl:value-of select="../@name"/>.<xsl:value-of select="@name"/>, 
+	list_float, <xsl:value-of select="@name"/>)
+  </xsl:template>
+
+  <xsl:template match="field[@type='list' and @of='string']" mode="serialize">
+	++ serialize_field(Message#<xsl:value-of select="../@name"/>.<xsl:value-of select="@name"/>, 
+	list_string, <xsl:value-of select="@name"/>)
+  </xsl:template>
+
+  <xsl:template match="field[@type='list' and @of='message']" mode="serialize">
+	++ serialize_field(Message#<xsl:value-of select="../@name"/>.<xsl:value-of select="@name"/>, 
+	list_message, <xsl:value-of select="@name"/>)
+  </xsl:template>
+
+  <xsl:template match="field" mode="serialize">
+	++ serialize_field(Message#<xsl:value-of select="../@name"/>.<xsl:value-of select="@name"/>, 
+	<xsl:value-of select="@type"/>, <xsl:value-of select="@name"/>)
+  </xsl:template>
+
+  <xsl:template match="message" mode="serialize">
+	serialize(Message=#<xsl:value-of select="@name"/>{}) <xsl:text disable-output-escaping="yes"> -></xsl:text>
+	_Result = "{\"<xsl:value-of select="@name"/>\" : {" 
+	<xsl:for-each select="field">
+	  <xsl:apply-templates select="." mode="serialize"/>
+	  <xsl:if test="position() != last()">
+		<xsl:text>++","  </xsl:text>
+      </xsl:if>
+	</xsl:for-each>
+	++ "}}"
+	;
+	
+  </xsl:template>
+
+
+<!-- deserialize templates -->
+  <!-- field deserialize -->
+  <xsl:template match="field[@type='string']" mode="deserialize">
+	<xsl:value-of select="@name"/> = binary_to_list(
+	proplists:get_value(<xsl:text>&lt;&lt;"</xsl:text><xsl:value-of select="@name"/><xsl:text>"&gt;&gt;</xsl:text>, MessageBody))
+  </xsl:template>
+
+  <xsl:template match="field[@type='int']" mode="deserialize">
+	<xsl:value-of select="@name"/> = bstring_to_int(
+	proplists:get_value(<xsl:text>&lt;&lt;"</xsl:text><xsl:value-of select="@name"/><xsl:text>"&gt;&gt;</xsl:text>, MessageBody))
+  </xsl:template>
+
+  <xsl:template match="field[@type='float']" mode="deserialize">
+	<xsl:value-of select="@name"/> = bstring_to_float(
+	proplists:get_value(<xsl:text>&lt;&lt;"</xsl:text><xsl:value-of select="@name"/><xsl:text>"&gt;&gt;</xsl:text>, MessageBody))
+  </xsl:template>
+
+  <xsl:template match="field[@type='message']" mode="deserialize">
+	<xsl:value-of select="@name"/> = deserialize_inner(
+		proplists:get_value(<xsl:text>&lt;&lt;"</xsl:text><xsl:value-of select="@name"/><xsl:text>"&gt;&gt;</xsl:text>, MessageBody)
+	)
+  </xsl:template>
+
+  <!-- lists deserialize -->
+  <xsl:template match="field[@type='list' and @of='int']" mode="deserialize">
+	<xsl:value-of select="@name"/> = deserialize_list(
+	proplists:get_value(<xsl:text>&lt;&lt;"</xsl:text><xsl:value-of select="@name"/><xsl:text>"&gt;&gt;</xsl:text>, MessageBody), 
+	int)
+  </xsl:template>
+
+  <xsl:template match="field[@type='list' and @of='float']" mode="deserialize">
+	<xsl:value-of select="@name"/> = deserialize_list(
+	proplists:get_value(<xsl:text>&lt;&lt;"</xsl:text><xsl:value-of select="@name"/><xsl:text>"&gt;&gt;</xsl:text>, MessageBody), 
+	float)
+  </xsl:template>
+
+  <xsl:template match="field[@type='list' and @of='string']" mode="deserialize">
+	<xsl:value-of select="@name"/> = deserialize_list(
+	proplists:get_value(<xsl:text>&lt;&lt;"</xsl:text><xsl:value-of select="@name"/><xsl:text>"&gt;&gt;</xsl:text>, MessageBody), 
+	string)
+  </xsl:template>
+
+  <xsl:template match="field[@type='list' and @of='message']" mode="deserialize">
+	<xsl:value-of select="@name"/> = deserialize_list(
+	proplists:get_value(<xsl:text>&lt;&lt;"</xsl:text><xsl:value-of select="@name"/><xsl:text>"&gt;&gt;</xsl:text>, MessageBody), 
+	message)
+  </xsl:template>
+
+
+  <xsl:template match="message" mode="deserialize">
+	<xsl:text>deserialize_message(</xsl:text>
+	<xsl:text>&lt;&lt;"</xsl:text><xsl:value-of select="@name"/><xsl:text>"&gt;&gt;</xsl:text>,
+	<xsl:text>MessageBody)</xsl:text>
+	<xsl:text disable-output-escaping="yes"> -></xsl:text>
+	#<xsl:value-of select="@name"/>{
+	<xsl:for-each select="field">
+	  <xsl:apply-templates select="." mode="deserialize"/>
+	  <xsl:if test="position() != last()">
+		<xsl:text>, </xsl:text>
+	  </xsl:if>
+	</xsl:for-each>
+	<xsl:text>};</xsl:text>
+	<xsl:text>&#10; </xsl:text>
+  </xsl:template>
+
+
+<!-- protocol template aka main -->
+  <xsl:template match="/protocol">
+	-module(<xsl:value-of select="@name"/>).
+	-export([serialize/1, deserialize/1]).
+	-include("protocol.hrl").
+	-import(lists).
+	-import(string).
+
+	<!-- deserialize list -->
+	deserialize_list(List, int) ->
+	    lists:map(fun(X) -> bstring_to_int(X) end, List);
+	deserialize_list(List, float) ->
+	    lists:map(fun(X) -> bstring_to_float(X) end, List);
+	deserialize_list(List, string) ->
+	    lists:map(fun(X) -> binary_to_list(X) end, List);
+	deserialize_list(List, message) ->
+	    lists:map(fun(X) -> deserialize_inner(X) end, List);
+	deserialize_list(_List, _Message) ->
+	    fail.
+
+	<!-- misc -->
+	bstring_to_int(Bstring) ->
+	    {Int, _Rest} = string:to_integer(binary_to_list(Bstring)),
+	    Int.
+
+	bstring_to_float(Bstring) ->
+	    {Float, _Rest} = string:to_float(binary_to_list(Bstring)),
+	    Float.
+
+
+	<!-- serialization -->
+	<xsl:text disable-output-escaping="yes">
+	serialize_list([H | T], Type) ->
+	   Head = serialize_field_inner(H, Type),
+	   Values = lists:concat(
+                            lists:map(
+                                     fun(Val) -> string:concat(", ", serialize_field_inner(Val, Type)) end,
+                                     T)
+                            ),
+	   string:concat(Head, Values);
+	serialize_list([], _Type) -> [].
+	
+
+	serialize_field_inner(Value, message) ->
+	    serialize(Value);
+	serialize_field_inner(Value, Type) ->
+	    lists:concat(['"', Value, '"']).
+
+    serialize_field(Value, int, Name) ->
+         lists:concat(['"', Name, '"', " : ", '"', Value, '"']);
+    serialize_field(Value, string, Name) ->
+	     lists:concat(['"', Name, '"', " : ", '"', Value, '"']);
+	serialize_field(Value, float, Name) ->
+	     lists:concat(['"', Name, '"', " : ", '"', Value, '"']);
+	serialize_field(Value, message, Name) ->
+	     lists:concat(['"', Name, '"', " : ", serialize_field_inner(Value, message)]);
+	serialize_field(Values, list_int, Name)  ->
+	     lists:concat(['"', Name, '"', " : ", '[', serialize_list(Values, int), ']']);
+	serialize_field(Values, list_float, Name)  ->
+	     lists:concat(['"', Name, '"', " : ", '[', serialize_list(Values, float), ']']);
+	serialize_field(Values, list_string, Name)  ->
+	     lists:concat(['"', Name, '"', " : ", '[', serialize_list(Values, string), ']']);
+	serialize_field(Values, list_message, Name)  ->
+	     lists:concat(['"', Name, '"', " : ", '[', serialize_list(Values, message), ']']);
+
+	
+	serialize_field(_Value, Type, Name) ->
+	     {unknow_type, Name, Type}.
+	    
+	</xsl:text>
+
+	
+	<xsl:apply-templates select="message" mode="serialize"/>
+	<xsl:text disable-output-escaping="yes">
+	  serialize(_AnyOther) ->
+         {failed}.
+	</xsl:text>
+
+	<!-- deserialization -->
+	<xsl:apply-templates select="message" mode="deserialize"/>
+	<xsl:text disable-output-escaping="yes">
+	  deserialize_message(_Uknown, _Body) ->
+	    failed.
+	</xsl:text>
+
+	deserialize(JsonData) <xsl:text disable-output-escaping="yes"> -></xsl:text>
+	    {struct, MessageSt} = mochijson2:decode(JsonData),    
+	    [MessageName] = proplists:get_keys(MessageSt),
+	    {struct, MessageBody} = proplists:get_value(MessageName, MessageSt),
+	    deserialize_message(MessageName, MessageBody).
+	
+	deserialize_inner(JsonData) <xsl:text disable-output-escaping="yes"> -></xsl:text>
+	    {struct, MessageSt} = JsonData,    
+	    [MessageName] = proplists:get_keys(MessageSt),
+	    {struct, MessageBody} = proplists:get_value(MessageName, MessageSt),
+	    deserialize_message(MessageName, MessageBody).
+	
+  </xsl:template>
+
+
+</xsl:stylesheet>

common/protocol/tools/protogen.py

+import getopt
+import sys
+import libxslt
+import libxml2
+
+class Config:
+    pass
+
+config = Config()
+
+def show_help():
+    print "Usage : protogen.py --help --xmlinput=file.xml -v --lang=[erl, js]"
+
+def main():
+    # get options
+    opts, args = getopt.getopt(sys.argv[1:], "hx:vl:o:", ["help", "xmlinput=", "output=", "lang="])
+    #traverse through options
+    config.verbose = False
+    config.xmlInput = "proto.xml"
+    config.lang = "erlang"
+    config.output = "proto.erl"
+    for opt, arg in opts:
+        if opt == "-v":
+            config.verbose = True
+        if opt in ("-h", "--help"):
+            show_help()
+        if opt in ("-x", "--xmlinput"):
+            config.xmlInput = arg
+        if opt in ("-o", "--output"):
+            config.output = arg
+        if opt in ("-l", "--lang"):
+            config.lang = arg
+    # generate protocol
+    generate_protocol(config.xmlInput, config.output, config.lang)
+    print "Bye! =)"
+
+
+
+def generate_protocol(xmlInput, output, lang):
+    print "[i] generating new protocol"
+    print "[i] protocol xml file is " + xmlInput
+    print "[i] selected language is " + lang
+    print "[i] result will be writed to " + output
+    print "[i] parsing files..."
+    generator = "./generators/" + lang + ".xslt"
+    xmldoc = libxml2.parseFile(xmlInput)
+    styledoc = libxml2.parseFile(generator)
+    style = libxslt.parseStylesheetDoc(styledoc)
+    print "[i] applying stylesheet..."
+    result = style.applyStylesheet(xmldoc, None)
+    print "[i] writing the result..."
+    style.saveResultToFilename(output, result, 0)
+    print "[i] cleanup..."
+    xmldoc.freeDoc()
+    style.freeStylesheet()
+    result.freeDoc()
+    
+    
+
+
+
+
+main()