728x90

https://www.bybit.com/en-US/register?affiliate_id=19476&group_id=0&group_type=1 

 

Bybit | Cryptocurrency Trading Platform

Bybit is one of the fastest growing cryptocurrency exchanges, with more than 2 million registered users. You can buy and sell crypto instantly, or trade popular coins across different contract types as you’d like.

www.bybit.com

바이비트에서 단독으로 진행중인 수수료할인 제휴 가입링크입니다 .

 

본 글을 읽고 이해가 안되시거나 도움이 필요하신분은 편하게 sososoll 로 카카오톡 문의주세요

 

 

 

 

선물거래하는 방법

바이비트(Bybit)는 3종류의 선물거래 상품을 제공합니다.

  • USDT Perpetual(USDT 무기한 계약) : 만기 날짜가 없으며, 테더(USDT)를 담보로 거래
  • Inverse Perpetual(인버스 무기한 계약) : 만기 날짜가 없으며, 코인을 담보로 거래
  • Inverse Futures(인버스 선물 계약) : 만기 날짜가 존재(만기일 명시), 기한 내에 청산하며 코인을 담보로 거래

 

필요에 따라 자신에게 맞는 유형의 상품을 선택하시길 바랍니다. 본 글에서는 인버스 무기한 계약을 예시로 설명드리겠습니다.

 

 

 

 

1. 파생상품(Derivatives) ➡︎ 인버스 계약(Inverse Contracts) ➡︎ 무기한(Perpetual) 종목 선택

인버스 계약(Inverse Contracts) 탭에 들어가면 인버스 무기한 계약(Perpetual)과 인버스 계약(Futures)이 존재합니다. 원하시는 항목을 선택 후, 거래 항목을 선택합니다. 리플/달러(XRPUSD)을 예시로 들겠습니다.

 

 

2. 레버리지(Leverage) 배수 설정 ➡︎ 격리(Isolated)/교차(Cross) 선택

여기서 레버리지(Leverage)와 투자 방식(Cross/Isolated), 주문 방식(Limit/Market/Conditional)을 설정합니다. 

 

 

 

 

레버리지(Leverage)는 자신이 투자한 금액의 몇 배만큼의 코인을 빌릴 지를 의미합니다. 예를 들어 x10 레버리지를 설정하여 1000만원을 투자하였다고 가정했을 때, 이는 1억원을 투자한 것과 같습니다. 따라서 10%만 상승해도 1000만원을 벌며, 반대로 10% 하락 시 1000만원을 잃어 강제청산을 당하는 것 입니다.

 

마진 모드(Margin Mode) : 격리(Isolated)와 교차(Cross)

교차(Isolated) : 투자 금액 외에 잔액을 담보로 잡음으로 강제청산 당할 가능성이 줄어들지만, 강제청산 당한다면 전액이 몰수될 수 있습니다.

격리(Cross) : 투자 금액만을 담보로 잡고 있기 때문에 강제청산 시 투자 금액만 날아가지만 강제청산 당할 가능성이 높아집니다.

 

 

 

2. 주문 가격(Order Price) 및 수량(Contract Qty) 입력

지정가(Limit)/조건부주문(Conditional)으로 선택 시 주문 가격(Order Price)를 입력하고, 주문 수량(Contract Qty)를 입력합니다.

 

3. 포지션(Position) 공매수(Long) / 공매도(Short) 선택 ➡︎ 주문 완료]

마지막으로 공매수(Buy/Long) 또는 공매도(Sell/Short) 중에 선택하여 주문을 완료합니다.

롱(Long)과 숏(Short)

 

롱(Long) : 특정 종목의 가격 상승을 예상하여 거래소에서 돈을 빌려 상승할 것 같은 종목에 투자하고, 상승했을 때 원금을 갚는 방식으로 차익을 얻는 것,

 

숏(Short) : 특정 종목의 가격 하락을 예상하여 그 항목을 보유하고 있지 않은 상태에서 빌린 후, 거래소에 팔고, 종목 하락 시 저렴한 가격으로 구매해 대여자에게 다시 돌려주는 방식으로 차익을 얻는 것

 

*인버스 무기한 계약은 코인을 담보로 하기 때문에 숏(Short)을 선택할 시, 코인 가격이 하락하면 수익을 얻는 동시에 코인의 가격이 떨어지기 때문에 손실도 발생합니다.

 

 

4. 청산(Close Position)

포지션(Positions)에 진입하면 지정가(Limit)와 시장가(Market) 버튼이 보이는데, 이를 통해서 목표가와 손절가를 설정 가능합니다. 지정가(Limit)를 클릭하면 목표 가격을 설정해두고 그 가격이 되면 얼마나 팔지 비중을 설정할 수 있습니다. 시장가(Market)를 클릭하면 해당 시점에서 시장가로 얼마나 매도 할 지 비중을 설정할 수 있습니다.

 

 

 

<2022년09월27일 글 직접 개발한 비트코인 자동매매 1달 돌린결과>

https://ititit1.tistory.com/141

 

직접 개발한 비트코인 자동매매(feat. Bybit ) 1달간 돌린 결과 공개 / 비트코인 자동매매 프로그램

https://partner.bybit.com/b/developer (바이비트 파트너 수수료할인 + 최대 600달러 증정금 지급 가입링크) Bybit | Cryptocurrency Trading Platform Bybit is one of the fastest growing cryptocurrency exch..

ititit1.tistory.com

 

 

 

이상으로 바이비트(Bybit) 선물거래 하는 방법에 대하여 말씀드렸습니다.

감사합니다.

 

https://www.bybit.com/en-US/register?affiliate_id=19476&group_id=0&group_type=1 

 

Bybit | Cryptocurrency Trading Platform

Bybit is one of the fastest growing cryptocurrency exchanges, with more than 2 million registered users. You can buy and sell crypto instantly, or trade popular coins across different contract types as you’d like.

www.bybit.com

 

728x90
728x90

upbit_V1.zip
0.00MB

1. 파이썬 설치 https://wikidocs.net/8 

이글을 보시고 똑같이 설치해주시면 됩니다.

 

01-4 파이썬 설치하기

이제 실습을 위해 컴퓨터에 파이썬을 설치해 보자. 이 책에서는 윈도우에서 설치하는 방법만 다룬다. 다른 시스템을 사용할 경우 파이썬 홈페이지([http://www.pytho ...

wikidocs.net

2. 파이썬을 성공적으로 설치하셨다면 CMD(명령 프롬프트) 를 키셔서 다음 명령어들을 입력합니다

pip install pyupbit

pip install Upbitpy

pip install upbitpy

pip install requests

 

3. 업비트에 로그인하여 API KEY 발급 (KEY는 노출되면 안됩니다. ip주소에는 네이버에 내ip를 검색하셔서 나오는 ip주소를 넣어주시면 됩니다.)

4. 시작메뉴에서 IDLE를 검색하여 실행해준후 Open을 눌러 다운받은 Upbit_v1.py 파일을 열어줍니다

5. 그러면 코드창이 나오는데 F5를 누르며 실행됩니다.

 

Access key와 secret key에 업비트에서 발급받은 키를 입력하시고

코인명에는 KRW-XRP 이런식으로(대문자) 입력해주시면 되고

Timesleep는 매수매도 사이의 시간간격입니다 빠르게 단주매매 돌리고싶으시면 0을 입력하시면 됩니다.

 

비트코인 후원 : 32mYRZMRFC4WZDDCjEVspZdgRzFAKuJk83

이더리움 후원 : 0x9f42fd9d94cC13b37009F587c242caC3b7Fe50F5

트론후원 : TNAWHsUWYNYZe8SYLBfEW7QBT76eVQFrm3

 

FTX거래소 파트너쉽 수수료 혜택 가입링크(평생 수수료할인)

https://ftx.com/#a=4826322

 

FTX

 

ftx.com

 

728x90
728x90

게임개발을 해본적이 단한번도 없는데 어쩌다보니 암호화폐 관련 프로그램들을 많이 만들고

다양하게 얕고 만들고싶은것들을 개발하다가 지인을 통해 우연히 외주를 받게되었고...

모바일 바카라 비슷한 게임제작 의뢰를 받게되었다.....모바일 게임에 암호화폐 지갑까지 연동해야 될수있는데

많이 힘들고 험난할거같지만

시간은 넉넉하니 천천히 개발해볼 생각이다.완전 C#도 배워본적없이 유니티를 시작하는거라 완전 기초부터 시작할 계획이다. 개발기간은 1달내에 오픈베타를 배포하는게 목표이고, 12월까지 최종배포를 하기로 하였다.

 

 

참고

https://doc.photonengine.com/ko-kr/pun/current/getting-started/pun-intro

https://www.youtube.com/watch?v=mPCNTi3Booo&list=PL3KKSXoBRRW3YE4UMnRH762vOhSHLdnpK 

https://doc.photonengine.com/ko-kr/pun/current/demos-and-tutorials/pun-basics-tutorial/lobby

https://mingyu0403.tistory.com/309?category=977479 

 

Photon과
연동하기 

https://dashboard.photonengine.com/en-US/ 

위 링크 포톤서버홈페이지에 접속하여 회원가입후 CRERATE A NEW APP을 통해 APP을 하나 만들어준다.

)무료버전이라 CCU는 20이라고 함). 우선 App-ID를 복사해놓는다

 

 

그리고 유니티 Asset 스토어에서 PUN2 -FREE를 다운로드 and Import 해준다.

 

 

Appid or email에는 아까 Photon서버에서 만든 app id를 복사 붙여넣기 해준후

Setup Project해주고 조금만 기다려주면 유니티와 연동이 된다.

 

실습 포톤서버와 연결하기

 

우선 화면을 다음과같이 구성해보았다.

 

꼭 필요한건  Text이다. 버튼은 이번실습에서 필요하지않고  다음 실습에서 다른화면으로 넘어가기위해(방입장) 미리 만들어놓았다.

 

화면을 다음과 같이 구성하였다면

 

 

 

NetworkManager라는 C#도 하나 만들어준다.

실습코드는 다음과 같습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine.UI;
 
public class NetworkManager : MonoBehaviourPunCallbacks
{
    string gameVersion = "1";
    public Text statusText;
    public string nick, roomname;
    public string connect_status;
 
 
    private void Awake()
    {
        PhotonNetwork.AutomaticallySyncScene = true;
        //스터 클라이언트와 일반 클라이언트들이 레벨을 동기화할지 결정한다.
        //true로 설정하면 마스터 클라에서 LoadLevel()로 레벨을 변경하면 모든 클라이언트들이 자동으로 동일한 레벨을 로드.
 
 
    }
 
    // Start is called before the first frame update
    void Start()
    {
        Connect();
    }
 
    // Update is called once per frame
    void Update()
    {
        
        statusText.text = PhotonNetwork.NetworkClientState.ToString();
    }
 
    public void Connect()
    {
 
        if (PhotonNetwork.IsConnected)
        {
            print("PhotonNetwork.IsConnected");
        }
        else
        {
            PhotonNetwork.GameVersion = gameVersion;
            PhotonNetwork.ConnectUsingSettings(); //Photon Online Server에 접속하기 가장 중요
        }
}
cs
 

 

 

 

콜백함수 정리

본인만의 코드를 통해 직접 Consol창에 찍어보면서 어떻게 호출되는지 학습하는게 좋을듯하다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine.UI;
 
public class NetworkManager : MonoBehaviourPunCallbacks
{
    string gameVersion = "1";
    public Text statusText;
    public string nick, roomname;
    public string connect_status;
 
 
    private void Awake()
    {
        print("awake");
        PhotonNetwork.AutomaticallySyncScene = true;
        //스터 클라이언트와 일반 클라이언트들이 레벨을 동기화할지 결정한다.
        //true로 설정하면 마스터 클라에서 LoadLevel()로 레벨을 변경하면 모든 클라이언트들이 자동으로 동일한 레벨을 로드.
 
 
    }
 
    // Start is called before the first frame update
    void Start()
    {
        print("start");
        Connect();
    }
 
    // Update is called once per frame
    void Update()
    {
        
        statusText.text = PhotonNetwork.NetworkClientState.ToString();
    }
 
    public void Connect()
    {
 
        if (PhotonNetwork.IsConnected)
        {
            print("PhotonNetwork.IsConnected");
        }
        else
        {
            PhotonNetwork.GameVersion = gameVersion;
            PhotonNetwork.ConnectUsingSettings(); //Photon Online Server에 접속하기 가장 중요
        }
 
 
    }
    public void Disconnect()
    {
        PhotonNetwork.Disconnect();
    }
    public void JoinLobby()
    {
        PhotonNetwork.JoinLobby();
    }
    public void CreateRoom()
    {
        // 방 생성하고, 참가.
        // 방 이름, 최대 플레이어 수, 비공개 등을 지정 가능.
        roomname = "room1";
        PhotonNetwork.CreateRoom(roomname, new RoomOptions { MaxPlayers = 6 });
    }
    public void JoinRoom()
    {
        // 방 참가하기.
        // 방 이름으로 입장 가능.
        PhotonNetwork.JoinRoom("room1");
    }
    public void JoinOrCreateRoom()
    {
        // 방 참가하는데, 방이 없으면 생성하고 참가.
        PhotonNetwork.JoinOrCreateRoom("room1"new RoomOptions { MaxPlayers = 6}, null);
    }
 
    //콜백함수들 
 
    //포톤 온라인 서버에 접속하면 불리는 콜백함수
    //PhotonNetwork.ConnectUsingSettings()가 성공하면 호출됨
    public override void OnConnectedToMaster()
    {
        print("서버 접속 완료.");
 
        // 현재 플레이어 닉네임 설정.
        nick = Random.Range(1100).ToString();
        PhotonNetwork.LocalPlayer.NickName = nick;
        
    }
 
    //연결이 끊기면 불리는 콜백함수
    //PhotonNetwork.Disconnect()가 성공하면 불린다.
    public override void OnDisconnected(DisconnectCause cause)
    {
        print("연결 끊김 누가? ->" + nick);
    }
 
    //로비에 접속하면 불리는 콜백함수
    //PhotonNetwork.JoinLobby()가 성공하면 호출됨
    public override void OnJoinedLobby()
    {
        base.OnJoinedLobby();
        {
            print("로비접속완료 누가? ->" + nick);
        }
    }
    // 방 생성하면 불리는 콜백 함수.
    // PhotonNetwork.CreateRoom()가 성공하면 불린다.
    public override void OnCreatedRoom()
    {
        print("방 만들기 완료 누가? ->" + nick);
        print("방 이름은 ? ->" + roomname);
    }
 
    /// 방 참가하면 불리는 콜백 함수.
    /// PhotonNetwork.CreateRoom(), PhotonNetwork.JoinedRoom()가 성공하면 불린다.
    public override void OnJoinedRoom()
    {
        print("방 참가완료 누가? ->" + nick);
        print("방 이름은 ? ->" + roomname);
    }
 
    //방생성 실패시 불리는 콜백함수
    //PhotonNetwork.CreateRoom()를 호출할때 이름이 같은 방이있ㅎ으면 실패할수있다.
    public override void OnCreateRoomFailed(short returnCode, string message)
    {
        print("방만들기 실패 " + message);
    }
 
    //방참가 실패시 호출되는 콜백함수
    //PhotonNetwork.JoinRoom()할때 방인원수가 꽉차있으면 실패,아래함수가 호출될수있다.
    public override void OnJoinRoomFailed(short returnCode, string message)
    {
        print("방 참가 실패.");
    }
 
    /// 방 랜덤 참가 실패하면 불리는 콜백 함수.
    /// PhotonNetwork.JoinRandomRoom()를 호출할 때, 방 인원수가 모두 차있거나 존재하지 않으면 실패할 수 있다.
    /// 다른 사람이 더 빠르게 들어갔거나, 방을 닫았을 수 있다.
 
    public override void OnJoinRandomFailed(short returnCode, string message)
    {
        print("방 랜덤 참가 실패.");
    }
}
 
cs

 

 

 

결과

c#코드를 모두 작성하였고 NetworkManager에 ADD COMPONENT  해줬다면 실습에서 콘솔에 다음과같이 뜰것이다.

 

작동과정을보면

1. Awake() 함수 PhotonNetwork.AutomaticallySyncScene = true;

//스터 클라이언트와 일반 클라이언트들이 레벨을 동기화할지 결정한다.

 

2. void Start()  -> Connect()

 

3.     public void Connect() 에서 if문이 거짓이므로(포톤서버와 연결이 안되있으므로) 

PhotonNetwork.GameVersion = gameVersion;
PhotonNetwork.ConnectUsingSettings(); 가 호출되고

 

4. PhotonNetwork.ConnectUsingSettings()가 성공하면 콜백함수    public override void OnConnectedToMaster() 가 호출됨

 

print("서버 접속 완료.");
// 현재 플레이어 닉네임 설정.
nick = Random.Range(1, 100).ToString();
PhotonNetwork.LocalPlayer.NickName = nick;

 

느낀점

유니티에서 사용되는 스크립트  C#언어를 사용해본적이 한번도 없는데

C#언어를 사용하는게 엄청 익숙하다.그러나  유니티 게임엔진을 이용하는게 아직 많이 어렵고 

부자연스럽다.. 오늘이 유니티학습 2일차인데, 유니티게임개발같은 경우 한국어

구글 자료가 좀 적은거같다고 느꼈다. 유니티 엔진을 좀더 자연스럽게 이용하기 위해 새벽에 

2D 점프게임 + 바카라 게임을 만들어봤다.

엄청 조잡하고 애니메이션효과도 하나도없지만 나름 재미있게 학습한거같다.( 이부분은 블로그에 포스팅하지않을거같다.

즉흥적으로 만든거라....)

 

포톤서버에 비용에대해 궁금해서 알아봤는데..

무료 포톤서버라 CCU(동시접속?)이 20명밖에 안된다고 한다.

동시접속 2000CCU가 월60만원 정도 하는거같다.

 

 

 

아래는 개별적으로 2D 위로 점프하는게임을 개발하면서 적은 메모장(낮과밤에는 내 프로젝트 관련된 유니티 프로젝트를 개발하고 , 그날 피곤하지않다면 내가 만들고싶은 간단한 게임을 만들면서 유니티와 친해져볼 생각이다.)

 

<< 게임 정리 >>

0. 화면에 객체(캐릭터) 등장
1. (클릭시) 객체를 일정높이까지 점프
2. 양쪽에서 발판들이 몰려온다
3. 아래에서 용암이 올라온다
4. 객체가 발판위에 안착하면 SCORE가 +1이 되고 SCORE에 점수가 갱신된다.

<< 필기 >>

'Scene' -> 작업하는 공간
'Game' -> 게임을 플레이할때 보이게 되는 화면

'Hierarchy' -> 장면에 등장하는 객체들 


Insperctor -> Transform 위치(T
                 ㄴ>  Component(Sprite Rendere ) : 기능

(객체 점프이벤트) 
1. 마우스 클릭이벤트를 인식 (클릭이벤트 리스너)
2. 클릭하면 어떠한 반응이 일어남
3. 주인공을 점푸할수 있는 상태로 만든다.
4. 주인공이 서있을 수 있는 바닥을 만든다.\

객체가 점프를 하기위해 객체에게 '질량' 을 부여하고
객체에게 '중력'을 부여하고 특정 이벤트 발생시
'하늘방향으로 힘을 가한다' 

Rigidbody 2d 컴포넌트는 트랜스폼을 오버라이드하고 
(부모 클래스로부터 상속받은 메소드를 재정의)

body type 에는 세가지 옵션
Dynamic : 동적
Kinematic 은 2d 시뮬레이션 상태에서,매우 명확한 사용자 제어 하에서 움직이도록 디자인되어있다.
Dynamic은 중력과 힘의 영향을 받음, 서로에게 영향을 미칠수 있음
Kinematic은 영향을 받지않는다.
Static은 전혀 움직이지 않도록 디자인 되었다.

2D(Colider2D)는 육체간의 충돌이 가능하게 해줌

★ GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 200.0f)) ★

구성요소(Componenent)의 육체(Rigidbody2D)를 가져와서 힘을가한다. 
어디로? > new Vector2(0,200,0f)방향으로 

<<문법>>

C#에서 다른클래스로 상속하려면 클래스 뒤에 : (콜론)을 추가하고 상속하려는 클래스명을 써주면됨

Square 객체클릭 -> Add Component -> New Script

스크립트(C#) 파일명을 Jump.cs

public class Jump : MonoBehaviour
{
    private void Update()
    {
        if(Input.GetMouseButtonDown(0) == true)
        {
            Debug.Log("마우스 클릭 발생");
        }
    }
}

Input.GetMouseButtonDown(0) == true
if parameter == 0    -> 좌클릭
if parameter == 1   -> 우클릭
if parameter ==2     -> 휠버튼 
누른순간 true로 변환되며 아무것도 안했을때
기본적으로 false로 구분됨

<점프 하기> 위해서 Square 객체에게 Component를 추가해주는데 컴퍼넌트는 'rigidbody 2d' 를 추가해준다.

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


text 바꾸기(ui: TextMeshProUGUI) 

public GameObject text1;
text1 연결
text1.GetComponent<TMPro.TextMeshProUGUI>().text ="123"

ㅡㅡㅡㅡㅡㅡㅡㅡ
포톤서버 APP-ID : 

이미지에서 Filter Mode를 Point로 하면 픽셀이 깨지지않고
Compression을 None로 하면 색이 번지지않음

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
서버/네트워크 프로그래밍
Mirror Mirage 네트워크라이브러리

728x90
728x90

게임 서버를 구현하려면 무엇이 필요한가?

서버/클라이언트 모델의 온라인 게임을 만들기 위해 게임서버 빌드를 만들고 호스팅해야 함

서버빌드 ->(서버 엔진파트 , 게임 컨텐츠 파트)

서버 엔진파트 -> Transport 설계, 소켓통신 , API등 전반적인 네트워킹과 관련된 것들을 구현

게임 컨텐츠 파트 -> 게임의 온라인 컨텐츠 기능을 구현하는 부분

 

서버 엔진파트를 구현하는 방법에는 크게 두가지가 존재

1. 자체적으로 성능과 필요한 기능 등을 고려해 서버 엔진을 팀에서 자체적으로 제작 하는 방법

장점으로는 서버기능의확장, 유지보수 용이, 구현하고자 하는 게임에 최적화도 가능, 구현방식을 자유롭게 선택할수있음

단점으로는 필요한 네트워크지식과 제작에 드는시간과 비용이 만만치않음

.

2. 이미 만들어진 게임서버 라이브러리와 제공되는 API를 이용하는 방법. 장ㅈ엄으로는 서버 엔진을 구현하는 시간과 비용을 절약, 네트워크 프로그래밍에 관한 지식이 없어도 API사용 방법만 익히면  멀티플레이를 구현할수 있다. 단점으로는 

라이브러리 내에 구현된 서버 엔진에 따라서 원하는 기능의 추가나 성능 최적화가 제한 될 수 있다.

 

 


Mirror & Mirage 네트워크 라이브러리



Unet으로부터 포크(fork)해 다수의 개발자들이 오픈소스로 참여하고 제작한 Mirror와 Mirror에서 포크하여 전문 서버 개발자들이 새롭게 제작한 Mirage

 

Mirror의 특징

1. HLAPI, Mirror를 사용하는 개발자들은 서버 엔진 단의 작동방식을 모르고 api만 잘 활용하면 손쉽게 멅이플레이를 구현가능

 

2. Low level의 Transport를 지원 , Mirror은 초기에 TCP베이스로 탄생하였으나 게임에 맞는 다른 Transport를 사용하면 

자동으로 성능최적화가 가능 ex) 빠른 페이스의 게임(액션,스포츠)에서는 TCP보다 UDP를 이용하기 좋은데 원하는 Low level의 통신(전송)을 mirror에서는 쉽게 적용가능

728x90
728x90

1. Manifest에 권한설정

<uses-permission android:name="android.permission.SEND_SMS"/>

 

<Manifest 전체 소스코드>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.whoami">

    <uses-permission android:name="android.permission.SEND_SMS"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.WhoAmI">
        <activity android:name=".MainActivity"
            android:exported="true">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 

2. SEND_SMS 권한 확인,요청

 

public void OnCheckPermission(){

    Log.d("jinsoltest","실행1");
    if(ActivityCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED
        || ActivityCompat.checkSelfPermission(this,Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED){

        if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.SEND_SMS)){
            Toast.makeText(this, "앱 실행을 위해서는 권한을 설정해야 합니다",Toast.LENGTH_SHORT).show();

            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.SEND_SMS, Manifest.permission.SEND_SMS},
                    PERMISSIONS_REQUEST
                    );
        } else{


            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.SEND_SMS, Manifest.permission.SEND_SMS},
                    PERMISSIONS_REQUEST);
        }
    }
}
728x90
728x90

https://www.youtube.com/watch?v=9l3uNWZOmTw 

 

대학교를 다니다 보면 항상 수강 신청하는 날이 무섭고 되게 떨립니다.

한 과목 한 과목 놓치면 자신의 공강이 사라지거나 , 점심시간이 사라지기도 하며

외롭게 혼자 학교를 다니게 될 수도 있으니까요

 

여기서 컴퓨터에 대해 조금 배우신분들이라면 분명 웹을 통해 수강신청서버와 통신을 하기때문에

코딩을 통해 똑같이 수강신청 서버가 열렸을때 서버로 수강신청 요청을 보내게되면

남들이 수강신청 서버에 접속이 몰릴때 , 따로 웹을통해 접속하지않고도

서버가 열리자마자 수강신청을 넣을수있습니다.

 

 

 

준비


수강신청 Requests 과정은 다음과같습니다.

 

수강신청을 하기전 대학교에 장바구니를 담는 날이 있습니다.

이때 Requests URL과 Cookies값들을 알아내고

과목별 Payload 딕셔너리 값들을 모두 알아내야 합니다.

 

Requests URL과 Payload값은 거의 변할일이 없지만

저희 학교같은경우 Cookies값의  SGJESSIONID값이 로그인할때마다 바뀌었습니다.

 

 

 

 

 

실습

크롬 F12(개발자모드)를 킨 상태에서 Network를 누른다음 

수강신청페이지(장바구니) 에 들어가서 아무과목이나 신청(or 장바구니담기) 버튼을 누릅니다.

그러면 Network 탭을 통해 모든 HTTP통신 과정을 볼 수 있습니다.

여기서 수강신청이 되는 요청과정이 분명있습니다.

저희학교같은경우 aply.do 였으며 

아주대의 경우 수강신청버튼을 눌러도 바로 수강신청서버로 요청이 가지않고

수강신청버튼클릭(요청) -> 보안문자 입력폼(응답) -> 옳게입력했을경우 수강신청서버로 수강신청Requests

 

네트워크 통신과정을 보면

capchaAnswer.action 이 보안문자 통신부분 ( payload값이 보안문자 입력값으로 전달됨) 옳바르게 입력했을경우

Response로 200값이 응답이 오게되고 바로 saveOpenLectureReg.ajax 를 통해 아주대 수강신청서버로 수강신청요청을 날리는것 같다.

 

 

 

 

 


 

 

 

 

 

 

 

 

한과목 수강신청 요청을 날리는 코드를 파이썬으로 짜봤다

우리학교의경우 보안문자 입력같은것이 없기때문에 되게 쉽게 구현이 가능함

다른학교들의경우 보안문자만 잘 해결하면 비슷비슷할거같다

 

실습코드(사회봉사 1학점짜리 수강신청코드)


import requests
import time

url='https://sugang.smu.ac.kr/UcrTlsn/aply.do'

cookies = {
    '_ga':'GA1.3.1726804677.1643137138',
    'WMONID':'jNFh1awnyxs',
    'SGJSESSIONID':'o153YzYsXcjHkQGgCaxr45rfQLQin1k44Zy2nuaxuPqvoQEW7x7qttHuS2NgtTAH.amV1c19kb21haW4vc3VnYW5nMQ=='
}

data = {
    '_AUTH_MENU_KEY': '',
'@d1#strSchYear': '2022',
'@d1#strSmtRcd': 'CMN002.0010',
'@d1#strSesRcd': 'CMN111.0000',
'@d1#strEstDeptCd': '00000',
'@d1#strEstShyr': '9',
'@d1#strSbjNo': 'HBRA1005',
'@d1#strDivcls': '1',
'@d1#strReTlsnSchYear': '',
'@d1#strReTlsnSmtRcd': '',
'@d1#strReTlsnSesRcd': '',
'@d1#strReTlsnSbjNo': '',
'@d#': '@d1#',
'@d1#': 'dmParamAply',
'@d1#tp': 'dm'
}

res = requests.post(url=url,cookies=cookies,data=data)
print("상태코드 :  " +  str(res))
print("수강신청요청결과  : " +  res.text)

 

위 코드를 수강신청 서버가 열릴시간때쯤 반복문을통해 요청을 보내면 빠르게 수강신청이 가능하다.

 

 

https://www.youtube.com/watch?v=9l3uNWZOmTw 

 

 

728x90
728x90

https://ititit1.tistory.com/114

 

CBT 바이낸스 리더보드 카피트레이딩 플랫폼 출시 / 비트겟 카피트레이딩 후기,단점)

카피트레이딩이란 쉽게 설명하면 내 계좌의 매수매도 권한 카피트레이더에게 맡겨 카피트레이더가 매수하면 똑같이 매수하고 매도하면 똑같이 매도하는 시스템입니다. 카피트레이딩은 아무래

ititit1.tistory.com

 

1. 호반꿀

호반꿀은 "박호두 반대로 하면 꿀빤다"의 약자입니다.

박호두는 해외선물,코인 선물 매매 방송(요즘은 코인만 합니다)을 하는 유튜버로 구독자는 35만명 가량 된다. 

 

 

2.호반꿀로 10억 벌고 경제적 자유를 달성한 박호두의 편집자

박호두 유튜브의 1등 공신 중 하나인 편집자 호튜브. 그 또한 투자 초장기에 박호두 반대매매-호반꿀 매매법으로 굉장히 이득을 많이 보았다고한다. 결국 가상화폐 투자로 10억을 넘게 벌고 현재는 편집자일을 그만두었다고함. 나중에 박호두 카페를 통해서 포르셰를 구매하여 인증하기도 했다.

 

 

제가 개발한 CBT 카피트레이딩 앱은 바이낸스 리더보드(랭킹)에서 원하는 트레이더를 골라

똑같이 매매를 진행하는 카피트레이딩 플랫폼인데요. 박호두 반대매매 시스템도 재미있을것 같아서 추가하였습니다.

 

 

자세한 내용은 아래링크로 가셔서 한번 읽어보시는걸 추천드립니다.

 

 

https://ititit1.tistory.com/114

 

CBT 바이낸스 리더보드 카피트레이딩 플랫폼 출시 / 비트겟 카피트레이딩 후기,단점)

카피트레이딩이란 쉽게 설명하면 내 계좌의 매수매도 권한 카피트레이더에게 맡겨 카피트레이더가 매수하면 똑같이 매수하고 매도하면 똑같이 매도하는 시스템입니다. 카피트레이딩은 아무래

ititit1.tistory.com

 

728x90
728x90

https://console.firebase.google.com/

 

로그인 - Google 계정

하나의 계정으로 모든 Google 서비스를 Google 계정으로 로그인

accounts.google.com

파이어베이스에서 데이터베이스를 만든 후 규칙을 다음과같이 허용해준다.

 

{
  "rules": {
    ".read": "true",
    ".write": "true"
  }
}

 

 

그 후 필드가 kind / name인 zoo테이블을 만든다.

 

 

 

 

그리고 animal 클래스를 만들어준다

 

//테이블이라고 생각하고, 테이블에 들어갈 속성값을 넣기
//파이어베이스는 RDBMS와 다르기 때문에 테이블이라는 개념이 없음. 원래는 키값이라고 부름
public class animal {
    String name; //동물 이름
    String kind; //동물 종류

    public animal(){} //이건 기본적으로 쓰더라구요.


    //get, set 함수는 커스텀 리스트 뷰를 사용하시는 분들과.. 필요하신 분만 작성하시면 좋습니다.
    public String getname() {
        return name;
    }

    public void setname(String name) {
        this.name = name;
    }

    public String getkind() {
        return kind;
    }

    public void setkind(String kind) {
        this.kind = kind;
    }

    //값을 추가할때 쓰는 함수, MainActivity에서 addanimal함수에서 사용할 것임.
    public animal(String name, String kind){
        this.name = name;
        this.kind = kind;
    }
}

 

 

 


데이터베이스 저장

 

 

이제 메인엑티비티에서 데이터베이스를 연동해줌 //전역변수로정의

 

// 파이어베이스 데이터베이스 연동
private final FirebaseDatabase database = FirebaseDatabase.getInstance();

//DatabaseReference는 데이터베이스의 특정 위치로 연결하는 거라고 생각하면 된다.
//현재 연결은 데이터베이스에만 딱 연결해놓고
//키값(테이블 또는 속성)의 위치 까지는 들어가지는 않은 모습이다.
private final DatabaseReference databaseReference = database.getReference();

 

public void addanimal(String name, String kind) {
    Log.d("jinsoltest","애니멀함수 ");
    //여기에서 직접 변수를 만들어서 값을 직접 넣는것도 가능합니다.
    // ex) 갓 태어난 동물만 입력해서 int age=1; 등을 넣는 경우

    //animal.java에서 선언했던 함수.
    animal animal = new animal(name,kind);

    //push()는 값을 넣을때 상위 키값을 랜덤으로 설정해 주는 함수입니다.
    //채팅기능을 만들때 사용하면 좋습니다.
    databaseReference.child("zoo").push().setValue(animal);
    //Toast.makeText(context,"db전송 :"+edit1.getText().toString()+" , "+edit2.getText().toString(),Toast.LENGTH_SHORT).show();

}

 


데이터베이스 읽기

 


public void ReadAnimal(){
    FirebaseDatabase.getInstance().getReference().addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                Log.d("jinsoltest", "ValueEventListener : " + snapshot.getValue());
            }
        }


        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });

}

 

Log가 잘찍힌것을 확인할수있다.

728x90
728x90

Fragment와 Activity에서 버튼이벤트를 발생시키는것은 조금 다르다. (Fragment는 android:onClick)를 사용x )

 

프래그먼트에서는 OnClickListener를 상속받아서 구현해줘야함. onClick메소드를 오버라이드 해줘야함

 

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    Log.d("jinsoltest","oncreateview 설취");
    View view = inflater.inflate(R.layout.fragment_search,container,false);
    edit1 = (EditText) view.findViewById(R.id.edit1);
    edit2 = (EditText) view.findViewById(R.id.edit2);
    Button btn_test = (Button) view.findViewById(R.id.btn_jinsol);

    btn_test.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            addanimal(edit1.getText().toString(),edit2.getText().toString());
        }
    });
    //이부분 중요
    return view;
}

 

이런식으로 코드를 짯을때 버튼이벤트가 발생하지않는다면

 

다음과같이 상속을받아 구현해보자.

 

 

public class SlideshowFragment extends Fragment implements View.OnClickListener {

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        View root = inflater.inflate(R.layout.fragment_slideshow, container, false);


        Button btn123 = root.findViewById(R.id.button1);
        btn123.setOnClickListener(this);
                
    }


    @Override
    public void onClick(View v) {
        switch(v.getId())
        {
            case R.id.top_layout:
            {
                if(isAvisiable) layout1.setVisibility(View.GONE);
                else layout1.setVisibility(View.VISIBLE);
                break;
            }

        }
    }
}

 

728x90
728x90

회원가입


 

0. 반드시 파이어베이스와 앱과 연동되어있어야함

 

1. 파이어베이스에 접속하여

 

Authemtication에서 이메일/비밀번호의 상태를 반드시 사용설정됨으로 수정

 

2. 

 

전역변수로 FirebaseAuth 변수 생성

private FirebaseAuth firebaseAuth;

 

OnCreate함수 안에서 

firebaseAuth = FirebaseAuth.getInstance();

if(email.length() > 8){
                    Log.d(TAG,"등록 버튼" + email + " , " + pwd);
                    final ProgressDialog mDialog = new ProgressDialog(register.this);
                    mDialog.setMessage("가입중입니다....");
                    mDialog.show();

                    //파이어베이스에 신규계정 등록하기
                    firebaseAuth.createUserWithEmailAndPassword(email,pwd).addOnCompleteListener(register.this, new OnCompleteListener<AuthResult>() {
                        @Override
                        public void onComplete(@NonNull Task<AuthResult> task) {

                            //가입 성공시
                            if(task.isSuccessful()){
                                mDialog.dismiss();

                                FirebaseUser user = firebaseAuth.getCurrentUser();
                                String email = user.getEmail();
                                String uid = user.getUid();


                                //해쉬맵 테이블을 파이어베이스 데이터베이스에 저장
                                HashMap<Object,String> hashmap = new HashMap<>();

                                hashmap.put("uid",uid);
                                hashmap.put("email",email);

                                FirebaseDatabase database = FirebaseDatabase.getInstance();
                                DatabaseReference reference = database.getReference("Users");
                                reference.child(uid).setValue(hashmap);

                                Intent intent = new Intent(register.this, MainActivity.class);
                                startActivity(intent);
                                finish();
                                Toast.makeText(register.this,"회원가입에 성공",Toast.LENGTH_SHORT).show();

                            }else{
                                mDialog.dismiss();
                                Toast.makeText(register.this, "이미 존재하는 아이디 입니다.", Toast.LENGTH_SHORT).show();
                                return; //해당 메소드 진행을 멈추고 빠져나감
                            }
                        }
                    });

                }else{
                    Toast.makeText(register.this, "올바른 이메일 주소를 입력해주세요", Toast.LENGTH_SHORT).show();
                    return;
                }

 


 

firebaseAuth.createUserWithEmailAndPassword.(이메일,패스워드).addOnCompleteListener(activity, OnCompleteListener<AuthResult>())

 

 

addOnCompleteListener

 

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
        .setDisplayName("Jane Q. User")
        .setPhotoUri(Uri.parse("https://example.com/jane-q-user/profile.jpg"))
        .build();

user.updateProfile(profileUpdates)
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "User profile updated.");
                }
            }
        });

 

 

 


로그인

 

String email = mEmailText.getText().toString().trim();
String pwd = mPasswordText.getText().toString().trim();
firebaseAuth.signInWithEmailAndPassword(email,pwd).addOnCompleteListener(MainActivity.this, new OnCompleteListener<AuthResult>() {
    @Override
    public void onComplete(@NonNull Task<AuthResult> task) {
        if(task.isSuccessful()){
            Intent intent = new Intent(MainActivity.this, CopyTrade.class);
            startActivity(intent);
        }else{
            Toast.makeText(MainActivity.this,"로그인 실패",Toast.LENGTH_SHORT).show();
        }
    }
});

 

 

 

728x90

+ Recent posts