📜 ⬆️ ⬇️

Interaction between multiple .bat, multiplayer on .bat


Bat files are not able to transmit any useful information to each other over the network.

No sockets, well, okay, but there is a simple work with named data areas, i.e. files. Creating and reading single-line text files is generally simplified to the limit. Just run echo Text> file.txt and file.txt will contain the string "Text". You can read a line from a file like this: set / p var = <file.txt (after execution, the var variable will contain the string "Text").

So, you can transfer information between batch files through files. And if these files are located on shared network resources, then batch files running on different computers can easily communicate with each other.

Here is a small example of a client-server application, such a rexec for the poor.

rexec_server.bat file:
set checkFolder=\\IMP5\PUBLIC_RW :loop @ping -n 2 127.0.0.1 > nul @if not exist "%checkFolder%\!cmd" goto loop @call "%checkFolder%\!command.bat" > "%checkFolder%\!result" @del "%checkFolder%\!cmd" @goto loop 

')
rexec_client.bat file:
 @echo off set checkFolder=\\IMP5\PUBLIC_RW :mainloop set /pc=^> if "%c%"=="exit" exit if "%c%"=="quit" exit echo %c%>"%checkFolder%\!command.bat" echo.>"%checkFolder%\!cmd" :waitloop ping -n 2 127.0.0.1 > nul if exist "%checkFolder%\!cmd" goto waitloop type "%checkFolder%\!result" del "%checkFolder%\!result" goto mainloop 


Here is an example of work:


It does the following: rexec_server.bat waits for the command line from the client and executes it on the computer on which it is running. He communicates with the client through the shared folder "\\ IMP5 \ PUBLIC_RW" (of course, you will need to replace it with your own if you want to experiment). So that the client and the server did not try to read ahead of time the files that are now being written for them, flag files were provided that serve only to indicate that the information has already been saved completely.

Well, for a snack - a multiplayer game on .bat "tic-tac-toe, three in a row."
Here, to preserve the integrity of the data, a critical section mechanism is implemented for blocking attempts to simultaneously access files.
Remember that before launching you need to specify your shared folder in the line “set FLAG_DIR = \\ IMP5 \ SHARED_RW” (by the way, several games can be played through one folder at a time).

Xo.bat file:
 @echo off cls set FLAG_DIR=\\IMP5\SHARED_RW call :create_chars :restart echo Please wait... call :sys_utils init "%0" set cmdPrefix=$p%__PID% rem ------- connecting -------- call :sys_utils enter_critical_section cls call :sys_utils fetch_flag ready_to_play if "%RESULT%"=="" ( call :sys_utils set_flag ready_to_play %cmdPrefix% set symbol=X set symbol2=O set server=1 ) else ( set cmdPrefix=%RESULT% call :sys_utils set_flag %RESULT%_client_ready --- set symbol=O set symbol2=X set server=0 ) call :sys_utils leave_critical_section if "%server%"=="0" goto client1 call :wait_for_client call :sys_utils set_flag %cmdPrefix%_server_ready_too --- goto skipClient1 :client1 call :wait_for_server if "%serverFailure%"=="1" goto restart :skipClient1 rem ------- connected -------- call :clear_field if "%server%"=="1" (set curMode=your_turn) else (set curMode=enemy_turn) :main_game_loop cls call :check_win call :render_field if "%winSymbol%"=="%symbol%" goto you_win if "%winSymbol%"=="%symbol2%" goto enemy_win if not "%curMode%"=="your_turn" goto skipTurn1 echo. echo Your are "%symbol%" echo. set /p tmp=Please enter <nul if "%f1%"=="1" set /p tmp=1, <nul if "%f2%"=="2" set /p tmp=2, <nul if "%f3%"=="3" set /p tmp=3, <nul if "%f4%"=="4" set /p tmp=4, <nul if "%f5%"=="5" set /p tmp=5, <nul if "%f6%"=="6" set /p tmp=6, <nul if "%f7%"=="7" set /p tmp=7, <nul if "%f8%"=="8" set /p tmp=8, <nul if "%f9%"=="9" set /p tmp=9, <nul echo or 'q' for quit echo. set /p "tmp=Your turn: " if "%tmp%"=="q" goto quit_game if "%tmp%"=="Q" goto quit_game call set varName=%%f%tmp%%% if not "%varName%"=="%tmp%" goto main_game_loop call set f%tmp%=%symbol% call :sys_utils set_flag %cmdPrefix%_%symbol%_move f%tmp% set curMode=enemy_turn goto main_game_loop :skipTurn1 if not "%curMode%"=="enemy_turn" goto skipTurn2 echo. echo Waiting for another player :wait_for_player0 set /p tmp=.<nul ping -n 2 127.0.0.1 > nul call :sys_utils fetch_flag %cmdPrefix%_%symbol2%_move if "%RESULT%"=="" goto wait_for_player0 echo %RESULT% if "%RESULT%"=="q" goto other_player_quit call set %RESULT%=%symbol2% set curMode=your_turn goto main_game_loop :skipTurn2 goto main_game_loop :quit_game call :sys_utils set_flag %cmdPrefix%_%symbol%_move q exit :other_player_quit cls echo Other player has left the game. echo Press 'Enter' to search for another one. pause > nul goto restart :you_win echo. echo You Win echo. echo Press 'Enter' pause > nul goto restart :enemy_win echo. echo You Lose echo. echo Press 'Enter' pause > nul goto restart :wait_for_client echo Waiting for client :wait_for_client1 set /p tmp=.<nul ping -n 2 127.0.0.1 > nul call :sys_utils fetch_flag %cmdPrefix%_client_ready if "%RESULT%"=="" goto wait_for_client1 exit /b :wait_for_server echo Waiting for server set serverFailure=0 set /a waitCnt=4 :wait_for_server1 set /a waitCnt-=1 if "%waitCnt%"=="0" ( set serverFailure=1 exit /b ) set /p tmp=.<nul ping -n 2 127.0.0.1 > nul call :sys_utils fetch_flag %cmdPrefix%_server_ready_too if "%RESULT%"=="" goto wait_for_server1 exit /b :clear_field set "f1=1" set "f2=2" set "f3=3" set "f4=4" set "f5=5" set "f6=6" set "f7=7" set "f8=8" set "f9=9" exit /b :create_chars set "charX0= # # ^|" set "charX1= # # ^|" set "charX2= # ^|" set "charX3= # # ^|" set "charX4= # # ^|" set "charX5=-------+" set "charO0= ### ^|" set "charO1= # # ^|" set "charO2= # # ^|" set "charO3= # # ^|" set "charO4= ### ^|" set "charO5=-------+" set "charXW0=.#...#.^|" set "charXW1=..#.#..^|" set "charXW2=...#...^|" set "charXW3=..#.#..^|" set "charXW4=.#...#.^|" set "charXW5=-------+" set "charOW0=..###..^|" set "charOW1=.#...#.^|" set "charOW2=.#...#.^|" set "charOW3=.#...#.^|" set "charOW4=..###..^|" set "charOW5=-------+" for %%i in (1,2,3,4,5,6,7,8,9) do call :create_empty_char %%i exit /b :create_empty_char set "char%10= ^|" set "char%11= ^|" set "char%12= %1 ^|" set "char%13= ^|" set "char%14= ^|" set "char%15=-------+" exit /b :check_win set winSymbol=. call :check3 1 2 3 call :check3 4 5 6 call :check3 7 8 9 call :check3 1 4 7 call :check3 2 5 8 call :check3 3 6 9 call :check3 1 5 9 call :check3 3 5 7 exit /b :check3 call set tmp1=%%f%1%%%%f%2%%%%f%3%% call set tmp2=%%f%1%%%%f%1%%%%f%1%% if "%tmp1%"=="%tmp2%" ( call set "winSymbol=%%f%1%%" call set "f%1=%%f%1%%W" call set "f%2=%%f%2%%W" call set "f%3=%%f%3%%W" ) exit /b :render_field call :render_line %f1% %f2% %f3% call :render_line %f4% %f5% %f6% call :render_line %f7% %f8% %f9% exit /b :render_line call echo %%char%10%%%%char%20%%%%char%30%% call echo %%char%11%%%%char%21%%%%char%31%% call echo %%char%12%%%%char%22%%%%char%32%% call echo %%char%13%%%%char%23%%%%char%33%% call echo %%char%14%%%%char%24%%%%char%34%% call echo %%char%15%%%%char%25%%%%char%35%% exit /b rem ----------------- atom -------------- :sys_utils goto %1 exit /b :init if "%FLAG_DIR%"=="" set FLAG_DIR=. set UNIQ_BAT_ID=%COMPUTERNAME%_%USERNAME%_%~n2 set /A CRITICAL_SECTION_LEVEL=0 call :enter_critical_section call :test_flag --null-- $pid$ set /A __PID=%RESULT% if [%__PID%]==[0] set /A __PID=10000000 if [%__PID%]==[] set /A __PID=10000000 if [%__PID%]==[99999999] set /A __PID=10000000 set /A __PID=__PID+1 call :set_flag --null-- $pid$ %__PID% call :leave_critical_section set UNIQ_BAT_ID=%UNIQ_BAT_ID%_pid%__PID% exit /b :set_flag call :enter_critical_section echo %3>"%FLAG_DIR%\%2" call :leave_critical_section exit /b :remove_flag call :enter_critical_section if exist "%FLAG_DIR%\%2" del "%FLAG_DIR%\%2" call :leave_critical_section exit /b :fetch_flag call :enter_critical_section set "RESULT=" if exist "%FLAG_DIR%\%2" ( set /p RESULT=<"%FLAG_DIR%\%2" del "%FLAG_DIR%\%2" ) call :leave_critical_section exit /b :test_flag call :enter_critical_section set "RESULT=" if exist "%FLAG_DIR%\%2" set /p RESULT=<"%FLAG_DIR%\%2" call :leave_critical_section exit /b :enter_critical_section set /A CRITICAL_SECTION_LEVEL=CRITICAL_SECTION_LEVEL+1 if not [%CRITICAL_SECTION_LEVEL%]==[1] exit /b set /A __WAIT_CNT=500 :wait_enter_critical_section set /A __WAIT_CNT=__WAIT_CNT-1 if [%__WAIT_CNT%]==[0] del "%FLAG_DIR%\$cs$_*" if exist "%FLAG_DIR%\$cs$_*" goto wait_enter_critical_section echo.>"%FLAG_DIR%\$cs$_%UNIQ_BAT_ID%" set /A __CNT=0 for %%i in ( "%FLAG_DIR%\$cs$_*" ) do set /a __CNT=__CNT+1 if [%__CNT%]==[1] goto all_right_1 del "%FLAG_DIR%\$cs$_%UNIQ_BAT_ID%" goto wait_enter_critical_section :all_right_1 exit /b :leave_critical_section set /A CRITICAL_SECTION_LEVEL=CRITICAL_SECTION_LEVEL-1 if [%CRITICAL_SECTION_LEVEL%]==[0] del "%FLAG_DIR%\$cs$_%UNIQ_BAT_ID%" exit /b :EOF 

Source: https://habr.com/ru/post/62919/


All Articles